// hwinobjimpl.h
#pragma once

#ifndef __HWINOBJIMPL_H__
#define __HWINOBJIMPL_H__

#include "hwinobj.h"

namespace harlinn
{
    namespace windows
    {

        class ComObjectBase : public IUnknown
        {
            long referenceCount;
            IUnknown* pUnknown;
            std::map<Guid,IUnknown*> interfaceMap;
        public:
            ComObjectBase()
                  : referenceCount(1),
                    pUnknown(0)
            {}

            ComObjectBase(IUnknown* theOuterUnknown)
                  : referenceCount(1),
                    pUnknown(theOuterUnknown)
            {}

            ComObjectBase(const ComObjectBase& other)
                  : referenceCount(1),
                    pUnknown(other.pUnknown)
            {}


            virtual ~ComObjectBase()
            {}


            ComObjectBase& InternalAddInterface(REFIID riid, IUnknown* pInterface )
            {
                if(pInterface)
                {
                    auto it = interfaceMap.find(riid);
                    if(it == interfaceMap.end())
                    {
                        interfaceMap.insert(std::map<Guid,IUnknown*>::value_type(riid,pInterface));
                    }
                }
                return *this;
            }

            IUnknown* InternalFindInterface(REFIID riid)
            {
                auto it = interfaceMap.find(riid);
                if(it != interfaceMap.end())
                {
                    return (*it).second;
                }
                return nullptr;
            }

            

            virtual HRESULT InternalQueryInterface( REFIID riid,void ** ppvObject )
            {
                if(!ppvObject)
                {
                    return E_INVALIDARG;
                }
                IUnknown* pInterface = InternalFindInterface(riid);
                if(pInterface)
                {
                    *ppvObject = pInterface;
                    pInterface->AddRef();
                    return NO_ERROR;
                }
                if(pUnknown)
                {
                    return pUnknown->QueryInterface(riid, ppvObject);
                }
                return E_NOINTERFACE;
            }

            ULONG InternalAddRef( )
            {
                long res = InterlockedIncrement(&referenceCount);
                return res;
            }

            HWIN_EXPORT ULONG InternalRelease( );
            
            virtual HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid,void ** ppvObject)
            {
                auto hr = this->InternalQueryInterface( riid,ppvObject);
                return hr;
            }

            virtual ULONG STDMETHODCALLTYPE AddRef( )
            {
                auto res = InternalAddRef( );
                return res;
            }

            virtual ULONG STDMETHODCALLTYPE Release( )
            {
                auto res = InternalRelease( );
                return res;
            }


        };

        template< typename Type_, typename Interface_ >
        class IUnknownImpl : public Interface_
        {
        public:
            typedef Type_ Type;
            typedef IUnknown InterfaceType;
            
        protected:
            Type* comObject;
        public:
            IUnknownImpl(Type* theComObject)
                : comObject(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IUnknown,this);
            }

            
            virtual HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid,void ** ppvObject)
            {
                auto hr = static_cast<Type*>(comObject)->InternalQueryInterface( riid,ppvObject);
                return hr;
            }

            virtual ULONG STDMETHODCALLTYPE AddRef( )
            {
                auto res = static_cast<Type*>(comObject)->InternalAddRef( );
                return res;
            }

            virtual ULONG STDMETHODCALLTYPE Release( )
            {
                auto res = static_cast<Type*>(comObject)->InternalRelease( );
                return res;
            }
            
        };


        template< typename Type_, typename Interface_ = IClassFactory >
        class IClassFactoryImpl : public IUnknownImpl< Type_ , Interface_>
        {
        public:
            typedef Type_ Type;
            typedef IClassFactory InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IClassFactoryImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE CreateInstance( IUnknown *pUnkOuter,REFIID riid, void **ppvObject)
            {
                auto res = static_cast<Type*>(comObject)->CreateInstance( pUnkOuter,riid, ppvObject);
                return res;
            }
            virtual HRESULT STDMETHODCALLTYPE LockServer( BOOL fLock)
            {
                auto res = static_cast<Type*>(comObject)->LockServer(fLock);
                return res;
            }
        };

        
        template< typename Type_, typename Interface_ = IClassFactory2 >
        class IClassFactory2Impl : public IClassFactoryImpl< Type_ , Interface_>
        {
        public:
            typedef Type_ Type;
            typedef IClassFactory2 InterfaceType;

            typedef IClassFactoryImpl< Type_, Interface_ > Base;
            IClassFactory2Impl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }
            virtual HRESULT STDMETHODCALLTYPE GetLicInfo( LICINFO *pLicInfo)
            {
                auto res = static_cast<Type*>(comObject)->GetLicInfo( pLicInfo);
                return res;
            }
            virtual HRESULT STDMETHODCALLTYPE RequestLicKey( DWORD dwReserved, BSTR *pBstrKey)
            {
                auto res = static_cast<Type*>(comObject)->RequestLicKey( dwReserved, pBstrKey);
                return res;
            }
            virtual HRESULT STDMETHODCALLTYPE CreateInstanceLic( IUnknown *pUnkOuter,IUnknown *pUnkReserved,REFIID riid,BSTR bstrKey,PVOID *ppvObj)
            {
                auto res = static_cast<Type*>(comObject)->CreateInstanceLic( pUnkOuter,pUnkReserved,riid,bstrKey,ppvObj);
                return res;
            }
        };


        template< typename Type_, typename Interface_ = IEnumUnknown >
        class IEnumUnknownImpl : public IUnknownImpl< Type_ , Interface_>
        {
        public:
            typedef Type_ Type;
            typedef IEnumUnknown InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IEnumUnknownImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE Next( ULONG celt, IUnknown **rgelt, ULONG *pceltFetched )
            {
                auto res = static_cast<Type*>(comObject)->Next( celt, rgelt, pceltFetched );
                return res;
            }
        
            virtual HRESULT STDMETHODCALLTYPE Skip( ULONG celt )
            {
                auto res = static_cast<Type*>(comObject)->Skip( celt );
                return res;
            }
        
            virtual HRESULT STDMETHODCALLTYPE Reset( )
            {
                auto res = static_cast<Type*>(comObject)->Reset( );
                return res;
            }
        
            virtual HRESULT STDMETHODCALLTYPE Clone(IEnumUnknown **ppenum)
            {
                auto res = static_cast<Type*>(comObject)->Clone(ppenum);
                return res;
            }
        };


        template< typename Type_, typename Interface_ = IEnumVARIANT >
        class IEnumVARIANTImpl : public IUnknownImpl< Type_ , Interface_>
        {
        public:
            typedef Type_ Type;
            typedef IEnumVARIANT InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IEnumVARIANTImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE Next( ULONG celt,VARIANT *rgVar,ULONG *pCeltFetched)
            {
                auto res = static_cast<Type*>(comObject)->Next( celt, rgVar, pCeltFetched );
                return res;
            }
        
            virtual HRESULT STDMETHODCALLTYPE Skip( ULONG celt)
            {
                auto res = static_cast<Type*>(comObject)->Skip( celt );
                return res;
            }
        
            virtual HRESULT STDMETHODCALLTYPE Reset( )
            {
                auto res = static_cast<Type*>(comObject)->Reset( );
                return res;
            }
        
            virtual HRESULT STDMETHODCALLTYPE Clone( IEnumVARIANT **ppEnum)
            {
                auto res = static_cast<Type*>(comObject)->Clone(ppEnum);
                return res;
            }
        };


        template< typename Type_, typename Interface_ = IEnumString >
        class IEnumStringImpl : public IUnknownImpl< Type_ , Interface_>
        {
        public:
            typedef Type_ Type;
            typedef IEnumString InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IEnumStringImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt,LPOLESTR *rgelt,ULONG *pceltFetched)
            {
                auto res = static_cast<Type*>(comObject)->Next(celt,rgelt,pceltFetched);
                return res;
            }
            virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
            {
                auto res = static_cast<Type*>(comObject)->Skip(celt);
                return res;
            }

            virtual HRESULT STDMETHODCALLTYPE Reset( )
            {
                auto res = static_cast<Type*>(comObject)->Reset( );
                return res;
            }

            virtual HRESULT STDMETHODCALLTYPE Clone(IEnumString **ppenum)
            {
                auto res = static_cast<Type*>(comObject)->Clone(ppenum);
                return res;
            }
        };



        template< typename Type_, typename Interface_ = IDispatch >
        class IDispatchImpl : public IUnknownImpl< Type_ , Interface_>
        {
        public:
            typedef Type_ Type;
            typedef IDispatch InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IDispatchImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo)
            {
                auto res = static_cast<Type*>(comObject)->GetTypeInfoCount(pctinfo);
                return res;
            }
            virtual HRESULT STDMETHODCALLTYPE GetTypeInfo( UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo)
            {
                auto res = static_cast<Type*>(comObject)->GetTypeInfo( iTInfo,lcid,ppTInfo);
                return res;
            }
            virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames( REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId)
            {
                auto res = static_cast<Type*>(comObject)->GetIDsOfNames( riid,rgszNames,cNames,lcid,rgDispId);
                return res;
            }
            virtual HRESULT STDMETHODCALLTYPE Invoke( DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr)
            {
                auto res = static_cast<Type*>(comObject)->Invoke( dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);
                return res;
            }

        };


        
        template< typename Type_, typename Interface_ = IProvideClassInfo >
        class IProvideClassInfoImpl : public IUnknownImpl< Type_ , Interface_>
        {
        public:
            typedef Type_ Type;
            typedef IProvideClassInfo InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IProvideClassInfoImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE GetClassInfo( ITypeInfo **ppTI)
            {
                return static_cast<Type*>(comObject)->GetClassInfo(ppTI);
            }
        };


        template< typename Type_, typename Interface_ = IProvideClassInfo >
        class IProvideClassInfo2Impl : public IProvideClassInfoImpl < Type_ , Interface_>
        {
        public:
            typedef Type_ Type;
            typedef IProvideClassInfo2 InterfaceType;

            typedef IProvideClassInfoImpl < Type_, Interface_ > Base;
            IProvideClassInfo2Impl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }
            virtual HRESULT STDMETHODCALLTYPE GetGUID( DWORD dwGuidKind,GUID *pGUID)
            {
                return static_cast<Type*>(comObject)->GetGUID( dwGuidKind,pGUID);
            }

        };

        
        template< typename Type_, typename Interface_ = IProvideClassInfo >
        class IProvideMultipleClassInfoImpl : public IProvideClassInfo2Impl < Type_ , Interface_>
        {
        public:
            typedef Type_ Type;
            typedef IProvideMultipleClassInfo InterfaceType;

            typedef IProvideClassInfo2Impl < Type_, Interface_ > Base;
            IProvideMultipleClassInfoImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }
            
            virtual HRESULT STDMETHODCALLTYPE GetMultiTypeInfoCount( ULONG *pcti)
            {
                return static_cast<Type*>(comObject)->GetMultiTypeInfoCount( pcti);
            }
            virtual HRESULT STDMETHODCALLTYPE GetInfoOfIndex( ULONG iti,DWORD dwFlags,ITypeInfo **pptiCoClass,DWORD *pdwTIFlags,ULONG *pcdispidReserved,IID *piidPrimary,IID *piidSource)
            {
                return static_cast<Type*>(comObject)->GetInfoOfIndex( iti,dwFlags,pptiCoClass,,pcdispidReserved,piidPrimary,piidSource);
            }

        };

        template< typename Type_, typename Interface_ = ISequentialStream >
        class ISequentialStreamImpl : public IUnknownImpl< Type_ , Interface_>
        {
        public:
            typedef Type_ Type;
            typedef ISequentialStream InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            ISequentialStreamImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_ISequentialStream,this);
            }

            virtual HRESULT STDMETHODCALLTYPE Read(void *pv,ULONG cb,ULONG *pcbRead)
            {
                return static_cast<Type*>(comObject)->Read(pv,cb,pcbRead);
            }
            virtual HRESULT STDMETHODCALLTYPE Write( const void *pv, ULONG cb, ULONG *pcbWritten)
            {
                return static_cast<Type*>(comObject)->Write( pv, cb, pcbWritten);
            }
        };


        template< typename Type_, typename Interface_ = IStream >
        class IStreamImpl : public virtual ISequentialStreamImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IStream InterfaceType;

            typedef ISequentialStreamImpl< Type_, Interface_ > Base;
            IStreamImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IStream,this);
            }


            virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER dlibMove,DWORD dwOrigin,ULARGE_INTEGER *plibNewPosition)
            {
                return static_cast<Type*>(comObject)->Seek(dlibMove,dwOrigin,plibNewPosition);
            }
        
            virtual HRESULT STDMETHODCALLTYPE SetSize( ULARGE_INTEGER libNewSize)
            {
                return static_cast<Type*>(comObject)->SetSize( libNewSize);
            }
        
            virtual HRESULT STDMETHODCALLTYPE CopyTo( IStream *pstm,ULARGE_INTEGER cb,ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
            {
                return static_cast<Type*>(comObject)->CopyTo(pstm,cb,pcbRead, pcbWritten);
            }
        
            virtual HRESULT STDMETHODCALLTYPE Commit(DWORD grfCommitFlags)
            {
                return static_cast<Type*>(comObject)->Commit(grfCommitFlags);
            }
        
            virtual HRESULT STDMETHODCALLTYPE Revert( )
            {
                return static_cast<Type*>(comObject)->Revert( );
            }
        
            virtual HRESULT STDMETHODCALLTYPE LockRegion( ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType)
            {
                return static_cast<Type*>(comObject)->LockRegion( libOffset,cb,dwLockType);
            }
        
            virtual HRESULT STDMETHODCALLTYPE UnlockRegion( ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType)
            {
                return static_cast<Type*>(comObject)->UnlockRegion( libOffset,cb,dwLockType);
            }
        
            virtual HRESULT STDMETHODCALLTYPE Stat( STATSTG *pstatstg,DWORD grfStatFlag)
            {
                return static_cast<Type*>(comObject)->Stat( pstatstg,grfStatFlag);
            }
        
            virtual HRESULT STDMETHODCALLTYPE Clone( IStream **ppstm )
            {
                return static_cast<Type*>(comObject)->Clone( ppstm );
            }

        };

        
        template< typename Type_, typename Interface_ = IOleAdviseHolder >
        class IOleAdviseHolderImpl : public IUnknownImpl< Type_ , Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleAdviseHolder InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IOleAdviseHolderImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IOleAdviseHolder,this);
            }

            virtual HRESULT STDMETHODCALLTYPE Advise( IAdviseSink *pAdvise,DWORD *pdwConnection)
            {
                return static_cast<Type*>(comObject)->Advise( pAdvise,pdwConnection);
            }
        
            virtual HRESULT STDMETHODCALLTYPE Unadvise(DWORD dwConnection)
            {
                return static_cast<Type*>(comObject)->Unadvise(dwConnection);
            }
        
            virtual HRESULT STDMETHODCALLTYPE EnumAdvise( IEnumSTATDATA **ppenumAdvise)
            {
                return static_cast<Type*>(comObject)->EnumAdvise( ppenumAdvise);
            }
        
            virtual HRESULT STDMETHODCALLTYPE SendOnRename( IMoniker *pmk)
            {
                return static_cast<Type*>(comObject)->SendOnRename( pmk);
            }
        
            virtual HRESULT STDMETHODCALLTYPE SendOnSave( )
            {
                return static_cast<Type*>(comObject)->SendOnSave( );
            }
        
            virtual HRESULT STDMETHODCALLTYPE SendOnClose( )
            {
                return static_cast<Type*>(comObject)->SendOnClose( );
            }
        };

        
        template< typename Type_, typename Interface_ = IOleCache >
        class IOleCacheImpl : public IUnknownImpl< Type_ , Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleCache InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IOleCacheImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE Cache( FORMATETC *pformatetc,DWORD advf,DWORD *pdwConnection)
            {
                return static_cast<Type*>(comObject)->Cache( pformatetc,advf,pdwConnection);
            }
            virtual HRESULT STDMETHODCALLTYPE Uncache(DWORD dwConnection)
            {
                return static_cast<Type*>(comObject)->Uncache(dwConnection);
            }
            virtual HRESULT STDMETHODCALLTYPE EnumCache( IEnumSTATDATA **ppenumSTATDATA)
            {
                return static_cast<Type*>(comObject)->EnumCache( ppenumSTATDATA);
            }
            virtual HRESULT STDMETHODCALLTYPE InitCache( IDataObject *pDataObject)
            {
                return static_cast<Type*>(comObject)->InitCache( pDataObject);
            }
            virtual HRESULT STDMETHODCALLTYPE SetData( FORMATETC *pformatetc,STGMEDIUM *pmedium,BOOL fRelease)
            {
                return static_cast<Type*>(comObject)->SetData( pformatetc,pmedium,fRelease);
            }
        };

        template< typename Type_, typename Interface_ = IOleCache2 >
        class IOleCache2Impl : public IOleCacheImpl< Type_ , Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleCache2 InterfaceType;

            typedef IOleCacheImpl< Type_, Interface_ > Base;
            IOleCache2Impl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE UpdateCache( LPDATAOBJECT pDataObject,DWORD grfUpdf,LPVOID pReserved)
            {
                return static_cast<Type*>(comObject)->UpdateCache( pDataObject,grfUpdf,pReserved);
            }

            virtual HRESULT STDMETHODCALLTYPE DiscardCache( DWORD dwDiscardOptions)
            {
                return static_cast<Type*>(comObject)->DiscardCache( dwDiscardOptions);
            }

        };

        
        template< typename Type_, typename Interface_ = IOleCacheControl >
        class IOleCacheControlImpl : public IUnknownImpl< Type_ , Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleCacheControl InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IOleCacheControlImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE OnRun( LPDATAOBJECT pDataObject)
            {
                return static_cast<Type*>(comObject)->OnRun( pDataObject);
            }
            virtual HRESULT STDMETHODCALLTYPE OnStop( )
            {
                return static_cast<Type*>(comObject)->OnStop( );
            }
        };

        
        template< typename Type_, typename Interface_ = IParseDisplayName >
        class IParseDisplayNameImpl : public IUnknownImpl< Type_ , Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IParseDisplayName InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IParseDisplayNameImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE ParseDisplayName( IBindCtx *pbc,LPOLESTR pszDisplayName,ULONG *pchEaten,IMoniker **ppmkOut)
            {
                return static_cast<Type*>(comObject)->ParseDisplayName( pbc,pszDisplayName,pchEaten,ppmkOut);
            }
        };

        
        template< typename Type_, typename Interface_ = IOleContainer >
        class IOleContainerImpl : public IParseDisplayNameImpl< Type_ , Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleContainer InterfaceType;

            typedef IParseDisplayNameImpl< Type_, Interface_ > Base;
            IOleContainerImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE EnumObjects( DWORD grfFlags,IEnumUnknown **ppenum)
            {
                return static_cast<Type*>(comObject)->EnumObjects( grfFlags,ppenum);
            }

            virtual HRESULT STDMETHODCALLTYPE LockContainer( BOOL fLock)
            {
                return static_cast<Type*>(comObject)->LockContainer( fLock);
            }
        };

        
        template< typename Type_, typename Interface_ = IOleClientSite >
        class IOleClientSiteImpl : public IUnknownImpl< Type_ , Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleClientSite InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IOleClientSiteImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE SaveObject( )
            {
                return static_cast<Type*>(comObject)->SaveObject( );
            }
            virtual HRESULT STDMETHODCALLTYPE GetMoniker( DWORD dwAssign,DWORD dwWhichMoniker,IMoniker **ppmk)
            {
                return static_cast<Type*>(comObject)->GetMoniker( dwAssign,dwWhichMoniker,ppmk);
            }
            virtual HRESULT STDMETHODCALLTYPE GetContainer( IOleContainer **ppContainer)
            {
                return static_cast<Type*>(comObject)->GetContainer(ppContainer);
            }
            virtual HRESULT STDMETHODCALLTYPE ShowObject( )
            {
                return static_cast<Type*>(comObject)->ShowObject( );
            }
            virtual HRESULT STDMETHODCALLTYPE OnShowWindow( BOOL fShow)
            {
                return static_cast<Type*>(comObject)->OnShowWindow( fShow);
            }
            virtual HRESULT STDMETHODCALLTYPE RequestNewObjectLayout( )
            {
                return static_cast<Type*>(comObject)->RequestNewObjectLayout( );
            }
        };


        template< typename Type_, typename Interface_ = IOleControl >
        class IOleControlImpl : public IUnknownImpl< Type_ , Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleControl InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IOleControlImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IOleControl,this);
            }


            virtual HRESULT STDMETHODCALLTYPE GetControlInfo(CONTROLINFO *pCI)
            {
                return static_cast<Type*>(comObject)->GetControlInfo(pCI);
            }
        
            virtual HRESULT STDMETHODCALLTYPE OnMnemonic(MSG *pMsg)
            {
                return static_cast<Type*>(comObject)->OnMnemonic(pMsg);
            }
        
            virtual HRESULT STDMETHODCALLTYPE OnAmbientPropertyChange(DISPID dispID)
            {
                return static_cast<Type*>(comObject)->OnAmbientPropertyChange(dispID);
            }
        
            virtual HRESULT STDMETHODCALLTYPE FreezeEvents(BOOL bFreeze)
            {
                return static_cast<Type*>(comObject)->FreezeEvents(bFreeze);
            }
        };

        
        template< typename Type_, typename Interface_ = IOleControlSite >
        class IOleControlSiteImpl : public IUnknownImpl< Type_ , Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleControlSite InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IOleControlSiteImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE OnControlInfoChanged( )
            {
                return static_cast<Type*>(comObject)->OnControlInfoChanged( );
            }
            virtual HRESULT STDMETHODCALLTYPE LockInPlaceActive( BOOL fLock)
            {
                return static_cast<Type*>(comObject)->LockInPlaceActive( fLock);
            }
            virtual HRESULT STDMETHODCALLTYPE GetExtendedControl( IDispatch **ppDisp)
            {
                return static_cast<Type*>(comObject)->GetExtendedControl( ppDisp);
            }
            virtual HRESULT STDMETHODCALLTYPE TransformCoords( POINTL *pPtlHimetric,POINTF *pPtfContainer, DWORD dwFlags)
            {
                return static_cast<Type*>(comObject)->TransformCoords( pPtlHimetric,pPtfContainer, dwFlags);
            }
            virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator( MSG *pMsg,DWORD grfModifiers)
            {
                return static_cast<Type*>(comObject)->TranslateAccelerator( pMsg,grfModifiers);
            }
            virtual HRESULT STDMETHODCALLTYPE OnFocus( BOOL fGotFocus)
            {
                return static_cast<Type*>(comObject)->OnFocus( fGotFocus);
            }
            virtual HRESULT STDMETHODCALLTYPE ShowPropertyFrame( )
            {
                return static_cast<Type*>(comObject)->ShowPropertyFrame();
            }

        };

        
        template< typename Type_, typename Interface_ = IPropertyPage >
        class IPropertyPageImpl : public IUnknownImpl< Type_ , Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IPropertyPage InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IPropertyPageImpl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE SetPageSite( IPropertyPageSite *pPageSite)
            {
                return static_cast<Type*>(comObject)->SetPageSite( pPageSite);
            }
            virtual HRESULT STDMETHODCALLTYPE Activate( HWND hWndParent,LPCRECT pRect,BOOL bModal)
            {
                return static_cast<Type*>(comObject)->Activate( hWndParent,pRect,bModal);
            }
            virtual HRESULT STDMETHODCALLTYPE Deactivate( )
            {
                return static_cast<Type*>(comObject)->Deactivate( );
            }
            virtual HRESULT STDMETHODCALLTYPE GetPageInfo( PROPPAGEINFO *pPageInfo)
            {
                return static_cast<Type*>(comObject)->GetPageInfo( pPageInfo);
            }
            virtual HRESULT STDMETHODCALLTYPE SetObjects( ULONG cObjects,IUnknown **ppUnk)
            {
                return static_cast<Type*>(comObject)->SetObjects( cObjects,ppUnk);
            }
            virtual HRESULT STDMETHODCALLTYPE Show( UINT nCmdShow)
            {
                return static_cast<Type*>(comObject)->Show( nCmdShow);
            }
            virtual HRESULT STDMETHODCALLTYPE Move( LPCRECT pRect)
            {
                return static_cast<Type*>(comObject)->Move( pRect);
            }
            virtual HRESULT STDMETHODCALLTYPE IsPageDirty( )
            {
                return static_cast<Type*>(comObject)->IsPageDirty( );
            }
            virtual HRESULT STDMETHODCALLTYPE Apply( )
            {
                return static_cast<Type*>(comObject)->Apply( );
            }
            virtual HRESULT STDMETHODCALLTYPE Help( LPCOLESTR pszHelpDir)
            {
                return static_cast<Type*>(comObject)->Help( pszHelpDir);
            }
            virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator( MSG *pMsg)
            {
                return static_cast<Type*>(comObject)->TranslateAccelerator( pMsg);
            }
        };

        
        template< typename Type_, typename Interface_ = IPropertyPage2 >
        class IPropertyPage2Impl : public IPropertyPageImpl< Type_ , Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IPropertyPage2 InterfaceType;

            typedef IPropertyPageImpl< Type_, Interface_ > Base;
            IPropertyPage2Impl(Type_* theComObject)
                : Base(theComObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE EditProperty( DISPID dispID)
            {
                return static_cast<Type*>(comObject)->EditProperty(dispID);
            }
        };

        
        template< typename Type_, typename Interface_ = IPropertyPageSite >
        class IPropertyPageSiteImpl : public IUnknownImpl< Type_ , Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IPropertyPageSite InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IPropertyPageSiteImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }
            virtual HRESULT STDMETHODCALLTYPE OnStatusChange(DWORD dwFlags) 
            {
                return static_cast<Type*>(comObject)->OnStatusChange(dwFlags) ;
            }
            virtual HRESULT STDMETHODCALLTYPE GetLocaleID( LCID *pLocaleID) 
            {
                return static_cast<Type*>(comObject)->GetLocaleID( pLocaleID) ;
            }
            virtual HRESULT STDMETHODCALLTYPE GetPageContainer( IUnknown **ppUnk)
            {
                return static_cast<Type*>(comObject)->GetPageContainer(ppUnk);
            }
            virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator( MSG *pMsg)
            {
                return static_cast<Type*>(comObject)->TranslateAccelerator(pMsg);
            }
        };
        
        template< typename Type_, typename Interface_ = IPropertyNotifySink >
        class IPropertyNotifySinkImpl : public IUnknownImpl< Type_ , Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IPropertyNotifySink InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IPropertyNotifySinkImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE OnChanged( DISPID dispID)
            {
                return static_cast<Type*>(comObject)->OnChanged( dispID);
            }
            virtual HRESULT STDMETHODCALLTYPE OnRequestEdit( DISPID dispID)
            {
                return static_cast<Type*>(comObject)->OnRequestEdit( dispID);
            }
        };

        
        template< typename Type_, typename Interface_ = ISpecifyPropertyPages >
        class ISpecifyPropertyPagesImpl : public IUnknownImpl< Type_ , Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef ISpecifyPropertyPages InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            ISpecifyPropertyPagesImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages)
            {
                return static_cast<Type*>(comObject)->GetPages(pPages);
            }

        };

        template< typename Type_, typename Interface_ = IOleObject >
        class IOleObjectImpl : public IUnknownImpl< Type_ , Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleObject InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IOleObjectImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IOleObject,this);
            }

            virtual HRESULT STDMETHODCALLTYPE SetClientSite(IOleClientSite *pClientSite)
            {
                return static_cast<Type*>(comObject)->SetClientSite(pClientSite);
            }
            virtual HRESULT STDMETHODCALLTYPE GetClientSite(IOleClientSite **ppClientSite)
            {
                return static_cast<Type*>(comObject)->GetClientSite(ppClientSite);
            }
            virtual HRESULT STDMETHODCALLTYPE SetHostNames( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
            {
                return static_cast<Type*>(comObject)->SetHostNames( szContainerApp, szContainerObj);
            }
            virtual HRESULT STDMETHODCALLTYPE Close(DWORD dwSaveOption )
            {
                return static_cast<Type*>(comObject)->Close( dwSaveOption );
            }
            virtual HRESULT STDMETHODCALLTYPE SetMoniker(DWORD dwWhichMoniker,IMoniker *pmk)
            {
                return static_cast<Type*>(comObject)->SetMoniker(dwWhichMoniker,pmk);
            }
            virtual HRESULT STDMETHODCALLTYPE GetMoniker( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
            {
                return static_cast<Type*>(comObject)->GetMoniker( dwAssign, dwWhichMoniker, ppmk);
            }
            virtual HRESULT STDMETHODCALLTYPE InitFromData( IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved)
            {
                return static_cast<Type*>(comObject)->InitFromData( pDataObject, fCreation, dwReserved);
            }
            virtual HRESULT STDMETHODCALLTYPE GetClipboardData( DWORD dwReserved, IDataObject **ppDataObject)
            {
                return static_cast<Type*>(comObject)->GetClipboardData( dwReserved, ppDataObject);
            }
            virtual HRESULT STDMETHODCALLTYPE DoVerb( LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
            {
                return static_cast<Type*>(comObject)->DoVerb( iVerb, lpmsg, pActiveSite, lindex, hwndParent, lprcPosRect);
            }
            virtual HRESULT STDMETHODCALLTYPE EnumVerbs( IEnumOLEVERB **ppEnumOleVerb )
            {
                return static_cast<Type*>(comObject)->EnumVerbs( ppEnumOleVerb );
            }
            virtual HRESULT STDMETHODCALLTYPE Update( )
            {
                return static_cast<Type*>(comObject)->Update( );
            }
            virtual HRESULT STDMETHODCALLTYPE IsUpToDate( )
            {
                return static_cast<Type*>(comObject)->IsUpToDate( );
            }
            virtual HRESULT STDMETHODCALLTYPE GetUserClassID( CLSID *pClsid)
            {
                return static_cast<Type*>(comObject)->GetUserClassID( pClsid );
            }
            virtual HRESULT STDMETHODCALLTYPE GetUserType( DWORD dwFormOfType,LPOLESTR *pszUserType)
            {
                return static_cast<Type*>(comObject)->GetUserType( dwFormOfType,pszUserType);
            }
            virtual HRESULT STDMETHODCALLTYPE SetExtent( DWORD dwDrawAspect,SIZEL *psizel)
            {
                return static_cast<Type*>(comObject)->SetExtent( dwDrawAspect,psizel);
            }
            virtual HRESULT STDMETHODCALLTYPE GetExtent( DWORD dwDrawAspect,SIZEL *psizel)
            {
                return static_cast<Type*>(comObject)->GetExtent( dwDrawAspect,psizel );
            }
            virtual HRESULT STDMETHODCALLTYPE Advise( IAdviseSink *pAdvSink,DWORD *pdwConnection)
            {
                return static_cast<Type*>(comObject)->Advise( pAdvSink, pdwConnection);
            }
            virtual HRESULT STDMETHODCALLTYPE Unadvise( DWORD dwConnection)
            {
                return static_cast<Type*>(comObject)->Unadvise( dwConnection );
            }
            virtual HRESULT STDMETHODCALLTYPE EnumAdvise( IEnumSTATDATA **ppenumAdvise)
            {
                return static_cast<Type*>(comObject)->EnumAdvise( ppenumAdvise );
            }
            virtual HRESULT STDMETHODCALLTYPE GetMiscStatus( DWORD dwAspect, DWORD *pdwStatus)
            {
                return static_cast<Type*>(comObject)->GetMiscStatus( dwAspect, pdwStatus);
            }
            virtual HRESULT STDMETHODCALLTYPE SetColorScheme( LOGPALETTE *pLogpal)
            {
                return static_cast<Type*>(comObject)->SetColorScheme( pLogpal );
            }
        };


        template< typename Type_, typename Interface_ = IOleWindow >
        class IOleWindowImpl : public IUnknownImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleWindow InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IOleWindowImpl( Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IOleWindow,this);
            }

            virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *phwnd)
            {
                return static_cast<Type*>(comObject)->GetWindow( phwnd );
            }
            virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode)
            {
                return static_cast<Type*>(comObject)->ContextSensitiveHelp( fEnterMode );
            }
        };


        template< typename Type_, typename Interface_ = IOleLink >
        class IOleLinkImpl : public IUnknownImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleLink InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IOleLinkImpl( Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE SetUpdateOptions( DWORD dwUpdateOpt)
            {
                return static_cast<Type*>(comObject)->SetUpdateOptions( dwUpdateOpt);
            }

            virtual HRESULT STDMETHODCALLTYPE GetUpdateOptions( DWORD *pdwUpdateOpt)
            {
                return static_cast<Type*>(comObject)->GetUpdateOptions( pdwUpdateOpt);
            }

            virtual HRESULT STDMETHODCALLTYPE SetSourceMoniker( IMoniker *pmk,REFCLSID rclsid)
            {
                return static_cast<Type*>(comObject)->SetSourceMoniker( pmk,rclsid);
            }

            virtual HRESULT STDMETHODCALLTYPE GetSourceMoniker( IMoniker **ppmk)
            {
                return static_cast<Type*>(comObject)->GetSourceMoniker( ppmk);
            }
            virtual HRESULT STDMETHODCALLTYPE SetSourceDisplayName( LPCOLESTR pszStatusText)
            {
                return static_cast<Type*>(comObject)->SetSourceDisplayName( pszStatusText);
            }
            virtual HRESULT STDMETHODCALLTYPE GetSourceDisplayName( LPOLESTR *ppszDisplayName)
            {
                return static_cast<Type*>(comObject)->GetSourceDisplayName( ppszDisplayName);
            }
            virtual HRESULT STDMETHODCALLTYPE BindToSource( DWORD bindflags,IBindCtx *pbc)
            {
                return static_cast<Type*>(comObject)->BindToSource( bindflags,pbc);
            }
            virtual HRESULT STDMETHODCALLTYPE BindIfRunning( ) 
            {
                return static_cast<Type*>(comObject)->BindIfRunning( );
            }

            virtual HRESULT STDMETHODCALLTYPE GetBoundSource( IUnknown **ppunk)
            {
                return static_cast<Type*>(comObject)->GetBoundSource( ppunk);
            }

            virtual HRESULT STDMETHODCALLTYPE UnbindSource( )
            {
                return static_cast<Type*>(comObject)->UnbindSource( );
            }
            virtual HRESULT STDMETHODCALLTYPE Update( IBindCtx *pbc)
            {
                return static_cast<Type*>(comObject)->Update( pbc);
            }
        };

        
        template< typename Type_, typename Interface_ = IOleItemContainer >
        class IOleItemContainerImpl : public IOleContainerImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleItemContainer InterfaceType;

            typedef IOleContainerImpl< Type_, Interface_ > Base;
            IOleItemContainerImpl( Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE GetObject( LPOLESTR pszItem,DWORD dwSpeedNeeded,IBindCtx *pbc,REFIID riid,void **ppvObject)
            {
                return static_cast<Type*>(comObject)->GetObject( pszItem,dwSpeedNeeded,pbc,riid,ppvObject);
            }
            virtual HRESULT STDMETHODCALLTYPE GetObjectStorage( LPOLESTR pszItem,IBindCtx *pbc,REFIID riid,void **ppvStorage)
            {
                return static_cast<Type*>(comObject)->GetObjectStorage( pszItem,pbc,riid,ppvStorage);
            }
            virtual HRESULT STDMETHODCALLTYPE IsRunning( LPOLESTR pszItem)
            {
                return static_cast<Type*>(comObject)->IsRunning( pszItem);
            }
        };


        
        template< typename Type_, typename Interface_ = IOleInPlaceUIWindow >
        class IOleInPlaceUIWindowImpl : public IOleWindowImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleInPlaceUIWindow InterfaceType;

            typedef IOleWindowImpl< Type_, Interface_ > Base;
            IOleInPlaceUIWindowImpl( Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE GetBorder( LPRECT lprectBorder)
            {
                return static_cast<Type*>(comObject)->GetBorder( lprectBorder);
            }

            virtual HRESULT STDMETHODCALLTYPE RequestBorderSpace( LPCBORDERWIDTHS pborderwidths)
            {
                return static_cast<Type*>(comObject)->RequestBorderSpace( pborderwidths);
            }

            virtual HRESULT STDMETHODCALLTYPE SetBorderSpace( LPCBORDERWIDTHS pborderwidths)
            {
                return static_cast<Type*>(comObject)->SetBorderSpace( pborderwidths);
            }

            virtual HRESULT STDMETHODCALLTYPE SetActiveObject( IOleInPlaceActiveObject *pActiveObject,LPCOLESTR pszObjName)
            {
                return static_cast<Type*>(comObject)->SetActiveObject( pActiveObject,pszObjName);
            }
        };

        
        template< typename Type_, typename Interface_ = IOleInPlaceObject >
        class IOleInPlaceObjectImpl : public IOleWindowImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleInPlaceObject InterfaceType;

            typedef IOleWindowImpl< Type_, Interface_ > Base;
            IOleInPlaceObjectImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IOleInPlaceObject,this);
            }

            virtual HRESULT STDMETHODCALLTYPE InPlaceDeactivate( )
            {
                return static_cast<Type*>(comObject)->InPlaceDeactivate( );
            }
            virtual HRESULT STDMETHODCALLTYPE UIDeactivate( )
            {
                return static_cast<Type*>(comObject)->UIDeactivate( );
            }
            virtual HRESULT STDMETHODCALLTYPE SetObjectRects( LPCRECT lprcPosRect, LPCRECT lprcClipRect)
            {
                return static_cast<Type*>(comObject)->SetObjectRects( lprcPosRect, lprcClipRect);
            }
            virtual HRESULT STDMETHODCALLTYPE ReactivateAndUndo( )
            {
                return static_cast<Type*>(comObject)->ReactivateAndUndo( );
            }
        };


        template< typename Type_, typename Interface_ = IOleInPlaceObjectWindowless >
        class IOleInPlaceObjectWindowlessImpl : public IOleInPlaceObjectImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleInPlaceObjectWindowless InterfaceType;

            typedef IOleInPlaceObjectImpl< Type_, Interface_ > Base;
            IOleInPlaceObjectWindowlessImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IOleInPlaceObject,this);
            }

            virtual HRESULT STDMETHODCALLTYPE OnWindowMessage( UINT msg,WPARAM wParam,LPARAM lParam,LRESULT *plResult)
            {
                return static_cast<Type*>(comObject)->OnWindowMessage( msg,wParam,lParam,plResult);
            }
            virtual HRESULT STDMETHODCALLTYPE GetDropTarget( IDropTarget **ppDropTarget)
            {
                return static_cast<Type*>(comObject)->GetDropTarget( ppDropTarget);
            }
        };

        
        template< typename Type_, typename Interface_ = IOleInPlaceSite >
        class IOleInPlaceSiteImpl : public IOleWindowImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleInPlaceSite InterfaceType;

            typedef IOleWindowImpl< Type_, Interface_ > Base;
            IOleInPlaceSiteImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE CanInPlaceActivate( )
            {
                return static_cast<Type*>(comObject)->CanInPlaceActivate( );
            }
            virtual HRESULT STDMETHODCALLTYPE OnInPlaceActivate( )
            {
                return static_cast<Type*>(comObject)->OnInPlaceActivate( );
            }
            virtual HRESULT STDMETHODCALLTYPE OnUIActivate( )
            {
                return static_cast<Type*>(comObject)->OnUIActivate( );
            }
            virtual HRESULT STDMETHODCALLTYPE GetWindowContext( IOleInPlaceFrame **ppFrame,IOleInPlaceUIWindow **ppDoc,LPRECT lprcPosRect,LPRECT lprcClipRect,LPOLEINPLACEFRAMEINFO lpFrameInfo) 
            {
                return static_cast<Type*>(comObject)->GetWindowContext( ppFrame,ppDoc,lprcPosRect,lprcClipRect,lpFrameInfo);
            }
            virtual HRESULT STDMETHODCALLTYPE Scroll( SIZE scrollExtant)
            {
                return static_cast<Type*>(comObject)->Scroll( scrollExtant);
            }
            virtual HRESULT STDMETHODCALLTYPE OnUIDeactivate( BOOL fUndoable)
            {
                return static_cast<Type*>(comObject)->OnUIDeactivate( fUndoable);
            }
            virtual HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate( )
            {
                return static_cast<Type*>(comObject)->OnInPlaceDeactivate( );
            }
            virtual HRESULT STDMETHODCALLTYPE DiscardUndoState( )
            {
                return static_cast<Type*>(comObject)->DiscardUndoState( );
            }
            virtual HRESULT STDMETHODCALLTYPE DeactivateAndUndo( )
            {
                return static_cast<Type*>(comObject)->DeactivateAndUndo( );
            }
            virtual HRESULT STDMETHODCALLTYPE OnPosRectChange( LPCRECT lprcPosRect)
            {
                return static_cast<Type*>(comObject)->OnPosRectChange( lprcPosRect);
            }
        };


        
        template< typename Type_, typename Interface_ = IOleInPlaceSiteEx >
        class IOleInPlaceSiteExImpl : public IOleInPlaceSiteImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleInPlaceSiteEx InterfaceType;

            typedef IOleInPlaceSiteImpl< Type_, Interface_ > Base;
            IOleInPlaceSiteExImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx( BOOL *pfNoRedraw,DWORD dwFlags)
            {
                return static_cast<Type*>(comObject)->OnInPlaceActivateEx( pfNoRedraw,dwFlags);
            }
            virtual HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx( BOOL fNoRedraw)
            {
                return static_cast<Type*>(comObject)->OnInPlaceDeactivateEx( fNoRedraw);
            }
            virtual HRESULT STDMETHODCALLTYPE RequestUIActivate( )
            {
                return static_cast<Type*>(comObject)->RequestUIActivate( );
            }
        };

        
        template< typename Type_, typename Interface_ = IOleInPlaceSiteWindowless >
        class IOleInPlaceSiteWindowlessImpl : public IOleInPlaceSiteExImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleInPlaceSiteWindowless InterfaceType;

            typedef IOleInPlaceSiteExImpl< Type_, Interface_ > Base;
            IOleInPlaceSiteWindowlessImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE CanWindowlessActivate( )
            {
                return static_cast<Type*>(comObject)->CanWindowlessActivate( );
            }
            virtual HRESULT STDMETHODCALLTYPE GetCapture( )
            {
                return static_cast<Type*>(comObject)->GetCapture( );
            }
        
            virtual HRESULT STDMETHODCALLTYPE SetCapture( BOOL fCapture)
            {
                return static_cast<Type*>(comObject)->SetCapture( fCapture);
            }
        
            virtual HRESULT STDMETHODCALLTYPE GetFocus( )
            {
                return static_cast<Type*>(comObject)->GetFocus( );
            }
        
            virtual HRESULT STDMETHODCALLTYPE SetFocus( BOOL fFocus)
            {
                return static_cast<Type*>(comObject)->SetFocus( fFocus);
            }
        
            virtual HRESULT STDMETHODCALLTYPE GetDC( LPCRECT pRect,DWORD grfFlags,HDC *phDC)
            {
                return static_cast<Type*>(comObject)->GetDC( pRect,grfFlags,phDC);
            }
        
            virtual HRESULT STDMETHODCALLTYPE ReleaseDC( HDC hDC)
            {
                return static_cast<Type*>(comObject)->ReleaseDC( hDC);
            }
        
            virtual HRESULT STDMETHODCALLTYPE InvalidateRect( LPCRECT pRect,BOOL fErase)
            {
                return static_cast<Type*>(comObject)->InvalidateRect( pRect,fErase);
            }
            virtual HRESULT STDMETHODCALLTYPE InvalidateRgn( HRGN hRGN,BOOL fErase)
            {
                return static_cast<Type*>(comObject)->InvalidateRgn( hRGN,fErase);
            }
        
            virtual HRESULT STDMETHODCALLTYPE ScrollRect( INT dx,INT dy,LPCRECT pRectScroll,LPCRECT pRectClip)
            {
                return static_cast<Type*>(comObject)->ScrollRect( dx,dy,pRectScroll,pRectClip);
            }
        
            virtual HRESULT STDMETHODCALLTYPE AdjustRect( LPRECT prc)
            {
                return static_cast<Type*>(comObject)->AdjustRect( prc);
            }
        
            virtual HRESULT STDMETHODCALLTYPE OnDefWindowMessage( UINT msg,WPARAM wParam,LPARAM lParam,LRESULT *plResult)
            {
                return static_cast<Type*>(comObject)->OnDefWindowMessage( msg,wParam,lParam,plResult);
            }

        };

        
        template< typename Type_, typename Interface_ = IContinue >
        class IContinueImpl : public IUnknownImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IContinue InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IContinueImpl( Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE FContinue( void)
            {
                return static_cast<Type*>(comObject)->FContinue();
            }

        };


        template< typename Type_, typename Interface_ = IOleInPlaceActiveObject >
        class IOleInPlaceActiveObjectImpl : public IOleWindowImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleInPlaceActiveObject InterfaceType;

            typedef IOleWindowImpl< Type_, Interface_ > Base;
            IOleInPlaceActiveObjectImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IOleInPlaceActiveObject,this);
            }

            virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg)
            {
                return static_cast<Type*>(comObject)->TranslateAccelerator(lpmsg);
            }
            virtual HRESULT STDMETHODCALLTYPE OnFrameWindowActivate(BOOL fActivate)
            {
                return static_cast<Type*>(comObject)->OnFrameWindowActivate(fActivate);
            }
            virtual HRESULT STDMETHODCALLTYPE OnDocWindowActivate( BOOL fActivate)
            {
                return static_cast<Type*>(comObject)->OnDocWindowActivate( fActivate);
            }
            virtual HRESULT STDMETHODCALLTYPE ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fFrameWindow)
            {
                return static_cast<Type*>(comObject)->ResizeBorder(prcBorder, pUIWindow, fFrameWindow);
            }
            virtual HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable)
            {
                return static_cast<Type*>(comObject)->EnableModeless(fEnable);
            }

        }; 

        
        template< typename Type_, typename Interface_ = IOleInPlaceFrame >
        class IOleInPlaceFrameImpl : public IOleInPlaceUIWindowImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IOleInPlaceFrame InterfaceType;

            typedef IOleInPlaceUIWindowImpl< Type_, Interface_ > Base;
            IOleInPlaceFrameImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT InsertMenus( HMENU hmenuShared,LPOLEMENUGROUPWIDTHS lpMenuWidths)
            {
                return static_cast<Type*>(comObject)->InsertMenus( hmenuShared,lpMenuWidths);
            }
            virtual HRESULT STDMETHODCALLTYPE SetMenu( HMENU hmenuShared,HOLEMENU holemenu,HWND hwndActiveObject)
            {
                return static_cast<Type*>(comObject)->SetMenu( hmenuShared,holemenu,hwndActiveObject);
            }
            virtual HRESULT STDMETHODCALLTYPE RemoveMenus( HMENU hmenuShared)
            {
                return static_cast<Type*>(comObject)->RemoveMenus( hmenuShared);
            }
            virtual HRESULT STDMETHODCALLTYPE SetStatusText( LPCOLESTR pszStatusText)
            {
                return static_cast<Type*>(comObject)->SetStatusText( pszStatusText);
            }
            virtual HRESULT STDMETHODCALLTYPE EnableModeless( BOOL fEnable)
            {
                return static_cast<Type*>(comObject)->EnableModeless( fEnable);
            }
            virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator( LPMSG lpmsg,WORD wID)
            {
                return static_cast<Type*>(comObject)->TranslateAccelerator( lpmsg,wID);
            }
        };

        template< typename Type_, typename Interface_ = IViewObject >
        class IViewObjectImpl : public IUnknownImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IViewObject InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IViewObjectImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IViewObject,this);
            }

            virtual HRESULT STDMETHODCALLTYPE Draw( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL ( STDMETHODCALLTYPE *pfnContinue )( ULONG_PTR dwContinue), ULONG_PTR dwContinue)
            {
                return static_cast<Type*>(comObject)->Draw( dwDrawAspect, lindex, pvAspect, ptd, hdcTargetDev, hdcDraw, lprcBounds, lprcWBounds, pfnContinue , dwContinue);
            }
            virtual HRESULT STDMETHODCALLTYPE GetColorSet( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet)
            {
                return static_cast<Type*>(comObject)->GetColorSet( dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, ppColorSet);
            }
            virtual HRESULT STDMETHODCALLTYPE Freeze( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze)
            {
                return static_cast<Type*>(comObject)->Freeze( dwDrawAspect, lindex, pvAspect, pdwFreeze);
            }
            virtual HRESULT STDMETHODCALLTYPE Unfreeze( DWORD dwFreeze)
            {
                return static_cast<Type*>(comObject)->Unfreeze( dwFreeze);
            }
            virtual HRESULT STDMETHODCALLTYPE SetAdvise( DWORD aspects,DWORD advf,IAdviseSink *pAdvSink)
            {
                return static_cast<Type*>(comObject)->SetAdvise( aspects,advf,pAdvSink);
            }
            virtual HRESULT STDMETHODCALLTYPE GetAdvise( DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink)
            {
                return static_cast<Type*>(comObject)->GetAdvise( pAspects, pAdvf, ppAdvSink);
            }
        };


        template< typename Type_, typename Interface_ = IViewObject2 >
        class IViewObject2Impl : public IViewObjectImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IViewObject2 InterfaceType;

            typedef IViewObjectImpl< Type_, Interface_ > Base;
            IViewObject2Impl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IViewObject2,this);
            }

            virtual HRESULT STDMETHODCALLTYPE GetExtent( DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE *ptd, LPSIZEL lpsizel)
            {
                return static_cast<Type*>(comObject)->GetExtent( dwDrawAspect, lindex, ptd, lpsizel);
            }
        };

        template< typename Type_, typename Interface_ = IViewObjectEx >
        class IViewObjectExImpl : public IViewObject2Impl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IViewObjectEx InterfaceType;

            typedef IViewObject2Impl< Type_, Interface_ > Base;
            IViewObjectExImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE GetRect( DWORD dwAspect,LPRECTL pRect)
            {
                return static_cast<Type*>(comObject)->GetRect( dwAspect,pRect);
            }
            virtual HRESULT STDMETHODCALLTYPE GetViewStatus( DWORD *pdwStatus)
            {
                return static_cast<Type*>(comObject)->GetViewStatus( pdwStatus);
            }
        
            virtual HRESULT STDMETHODCALLTYPE QueryHitPoint( DWORD dwAspect,LPCRECT pRectBounds,POINT ptlLoc,LONG lCloseHint,DWORD *pHitResult)
            {
                return static_cast<Type*>(comObject)->QueryHitPoint( dwAspect,pRectBounds,ptlLoc,lCloseHint,pHitResult);
            }
        
            virtual HRESULT STDMETHODCALLTYPE QueryHitRect( DWORD dwAspect,LPCRECT pRectBounds,LPCRECT pRectLoc,LONG lCloseHint,DWORD *pHitResult)
            {
                return static_cast<Type*>(comObject)->QueryHitRect( dwAspect,pRectBounds,pRectLoc,lCloseHint,pHitResult);
            }
        
            virtual HRESULT STDMETHODCALLTYPE GetNaturalExtent( DWORD dwAspect,LONG lindex,DVTARGETDEVICE *ptd,HDC hicTargetDev,DVEXTENTINFO *pExtentInfo,LPSIZEL pSizel)
            {
                return static_cast<Type*>(comObject)->GetNaturalExtent( dwAspect,lindex,ptd,hicTargetDev,pExtentInfo,pSizel);
            }

        };



        template< typename Type_, typename Interface_ = IOleUndoUnit >
        class IOleUndoUnitImpl : public IUnknownImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IOleUndoUnit InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IOleUndoUnitImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE Do( IOleUndoManager *pUndoManager)
            {
                return static_cast<Type*>(comObject)->Do(pUndoManager);
            }
            virtual HRESULT STDMETHODCALLTYPE GetDescription( BSTR *pBstr)
            {
                return static_cast<Type*>(comObject)->GetDescription( pBstr);
            }
        
            virtual HRESULT STDMETHODCALLTYPE GetUnitType( CLSID *pClsid,LONG *plID)
            {
                return static_cast<Type*>(comObject)->GetUnitType( pClsid,plID);
            }
        
            virtual HRESULT STDMETHODCALLTYPE OnNextAdd( )
            {
                return static_cast<Type*>(comObject)->OnNextAdd( );
            }
        };

        
        template< typename Type_, typename Interface_ = IOleParentUndoUnit >
        class IOleParentUndoUnitImpl : public IOleUndoUnitImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IOleParentUndoUnit InterfaceType;

            typedef IOleUndoUnitImpl< Type_, Interface_ > Base;
            IOleParentUndoUnitImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE Open( IOleParentUndoUnit *pPUU)
            {
                return static_cast<Type*>(comObject)->Open( pPUU);
            }
            virtual HRESULT STDMETHODCALLTYPE Close( IOleParentUndoUnit *pPUU,BOOL fCommit)
            {
                return static_cast<Type*>(comObject)->Close( pPUU,fCommit);
            }
        
            virtual HRESULT STDMETHODCALLTYPE Add( IOleUndoUnit *pUU) 
            {
                return static_cast<Type*>(comObject)->Add( pUU) ;
            }
        
            virtual HRESULT STDMETHODCALLTYPE FindUnit( IOleUndoUnit *pUU)
            {
                return static_cast<Type*>(comObject)->FindUnit( pUU);
            }
        
            virtual HRESULT STDMETHODCALLTYPE GetParentState( DWORD *pdwState)
            {
                return static_cast<Type*>(comObject)->GetParentState( pdwState);
            }
        };

        template< typename Type_, typename Interface_ = IEnumOleUndoUnits >
        class IEnumOleUndoUnitsImpl : public IUnknownImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IEnumOleUndoUnits InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IEnumOleUndoUnitsImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE Next( ULONG cElt,IOleUndoUnit **rgElt,ULONG *pcEltFetched)
            {
                return static_cast<Type*>(comObject)->Next( cElt,rgElt,pcEltFetched);
            }
            virtual HRESULT STDMETHODCALLTYPE Skip( ULONG cElt)
            {
                return static_cast<Type*>(comObject)->Skip( cElt);
            }
        
            virtual HRESULT STDMETHODCALLTYPE Reset( )
            {
                return static_cast<Type*>(comObject)->Reset( );
            }
        
            virtual HRESULT STDMETHODCALLTYPE Clone( IEnumOleUndoUnits **ppEnum)
            {
                return static_cast<Type*>(comObject)->Clone(ppEnum);
            }
        };

        
        template< typename Type_, typename Interface_ = IOleUndoManager >
        class IOleUndoManagerImpl : public IUnknownImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IOleUndoManager InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IOleUndoManagerImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE Open( IOleParentUndoUnit *pPUU)
            {
                return static_cast<Type*>(comObject)->Open( pPUU);
            }
            virtual HRESULT STDMETHODCALLTYPE Close( IOleParentUndoUnit *pPUU,BOOL fCommit)
            {
                return static_cast<Type*>(comObject)->Close( pPUU,fCommit);
            }
        
            virtual HRESULT STDMETHODCALLTYPE Add( IOleUndoUnit *pUU)
            {
                return static_cast<Type*>(comObject)->Add( pUU);
            }
        
            virtual HRESULT STDMETHODCALLTYPE GetOpenParentState( DWORD *pdwState)
            {
                return static_cast<Type*>(comObject)->GetOpenParentState( pdwState);
            }
        
            virtual HRESULT STDMETHODCALLTYPE DiscardFrom( IOleUndoUnit *pUU)
            {
                return static_cast<Type*>(comObject)->DiscardFrom( pUU);
            }
        
            virtual HRESULT STDMETHODCALLTYPE UndoTo( IOleUndoUnit *pUU)
            {
                return static_cast<Type*>(comObject)->UndoTo( pUU);
            }
        
            virtual HRESULT STDMETHODCALLTYPE RedoTo( IOleUndoUnit *pUU)
            {
                return static_cast<Type*>(comObject)->RedoTo( pUU);
            }
        
            virtual HRESULT STDMETHODCALLTYPE EnumUndoable( IEnumOleUndoUnits **ppEnum)
            {
                return static_cast<Type*>(comObject)->EnumUndoable( ppEnum);
            }
        
            virtual HRESULT STDMETHODCALLTYPE EnumRedoable( IEnumOleUndoUnits **ppEnum)
            {
                return static_cast<Type*>(comObject)->EnumRedoable( ppEnum);
            }
        
            virtual HRESULT STDMETHODCALLTYPE GetLastUndoDescription( BSTR *pBstr)
            {
                return static_cast<Type*>(comObject)->GetLastUndoDescription( pBstr);
            }
        
            virtual HRESULT STDMETHODCALLTYPE GetLastRedoDescription( BSTR *pBstr)
            {
                return static_cast<Type*>(comObject)->GetLastRedoDescription( pBstr);
            }
        
            virtual HRESULT STDMETHODCALLTYPE Enable( BOOL fEnable)
            {
                return static_cast<Type*>(comObject)->Enable( fEnable);
            }
        };

        template< typename Type_, typename Interface_ = IPointerInactive >
        class IPointerInactiveImpl : public IUnknownImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IPointerInactive InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IPointerInactiveImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE GetActivationPolicy( DWORD *pdwPolicy)
            {
                return static_cast<Type*>(comObject)->GetActivationPolicy( pdwPolicy);
            }
            virtual HRESULT STDMETHODCALLTYPE OnInactiveMouseMove( LPCRECT pRectBounds,LONG x,LONG y,DWORD grfKeyState)
            {
                return static_cast<Type*>(comObject)->OnInactiveMouseMove( pRectBounds,x,y,grfKeyState);
            }
        
            virtual HRESULT STDMETHODCALLTYPE OnInactiveSetCursor( LPCRECT pRectBounds,LONG x,LONG y,DWORD dwMouseMsg,BOOL fSetAlways)
            {
                return static_cast<Type*>(comObject)->OnInactiveSetCursor( pRectBounds,x,y,dwMouseMsg,fSetAlways);
            }
        };


        template< typename Type_, typename Interface_ = IObjectWithSite >
        class IObjectWithSiteImpl : public IUnknownImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IObjectWithSite InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IObjectWithSiteImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE SetSite( IUnknown *pUnkSite)
            {
                return static_cast<Type*>(comObject)->SetSite(pUnkSite);
            }
            virtual HRESULT STDMETHODCALLTYPE GetSite( REFIID riid,void **ppvSite) 
            {
                return static_cast<Type*>(comObject)->GetSite( riid,ppvSite) ;
            }

        };


        
        template< typename Type_, typename Interface_ = IPerPropertyBrowsing >
        class IPerPropertyBrowsingImpl : public IUnknownImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IPerPropertyBrowsing InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IPerPropertyBrowsingImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE GetDisplayString( DISPID dispID,BSTR *pBstr)
            {
                return static_cast<Type*>(comObject)->GetDisplayString( DISPID dispID,BSTR *pBstr);
            }
            virtual HRESULT STDMETHODCALLTYPE MapPropertyToPage( DISPID dispID,CLSID *pClsid)
            {
                return static_cast<Type*>(comObject)->MapPropertyToPage( dispID,pClsid);
            }
            virtual HRESULT STDMETHODCALLTYPE GetPredefinedStrings( DISPID dispID,CALPOLESTR *pCaStringsOut,CADWORD *pCaCookiesOut)
            {
                return static_cast<Type*>(comObject)->GetPredefinedStrings( dispID,pCaStringsOut,pCaCookiesOut);
            }
            virtual HRESULT STDMETHODCALLTYPE GetPredefinedValue( DISPID dispID,DWORD dwCookie,VARIANT *pVarOut)
            {
                return static_cast<Type*>(comObject)->GetPredefinedValue( dispID,dwCookie,pVarOut);
            }
        };

        template< typename Type_, typename Interface_ = IPropertyBag2 >
        class IPropertyBag2Impl : public IUnknownImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IPropertyBag2 InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IPropertyBag2Impl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE Read( ULONG cProperties,PROPBAG2 *pPropBag,IErrorLog *pErrLog,VARIANT *pvarValue,HRESULT *phrError)
            {
                return static_cast<Type*>(comObject)->Read( cProperties,pPropBag,pErrLog,pvarValue,phrError);
            }
            virtual HRESULT STDMETHODCALLTYPE Write( ULONG cProperties,PROPBAG2 *pPropBag,VARIANT *pvarValue)
            {
                return static_cast<Type*>(comObject)->Write( cProperties,pPropBag,pvarValue);
            }
        
            virtual HRESULT STDMETHODCALLTYPE CountProperties( ULONG *pcProperties)
            {
                return static_cast<Type*>(comObject)->CountProperties( pcProperties);
            }
        
            virtual HRESULT STDMETHODCALLTYPE GetPropertyInfo( ULONG iProperty,ULONG cProperties,PROPBAG2 *pPropBag,ULONG *pcProperties)
            {
                return static_cast<Type*>(comObject)->GetPropertyInfo( iProperty,cProperties,pPropBag,pcProperties);
            }
        
            virtual HRESULT STDMETHODCALLTYPE LoadObject( LPCOLESTR pstrName,DWORD dwHint,IUnknown *pUnkObject,IErrorLog *pErrLog)
            {
                return static_cast<Type*>(comObject)->LoadObject( pstrName,dwHint,pUnkObject,pErrLog);
            }

        };

        
        template< typename Type_, typename Interface_ = IPersist >
        class IPersistImpl : public IUnknownImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IPersist InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IPersistImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IPersist,this);
            }

            virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID)
            {
                return static_cast<Type*>(comObject)->GetClassID(pClassID);
            }
        };


        template< typename Type_, typename Interface_ = IPersistPropertyBag2 >
        class IPersistPropertyBag2Impl : public IPersistImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IPersistPropertyBag2 InterfaceType;

            typedef IPersistPropertyBag2Impl< Type_, Interface_ > Base;
            IPersistPropertyBag2Impl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE InitNew( )
            {
                return static_cast<Type*>(comObject)->InitNew( );
            }

            virtual HRESULT STDMETHODCALLTYPE Load( IPropertyBag2 *pPropBag,IErrorLog *pErrLog)
            {
                return static_cast<Type*>(comObject)->Load( pPropBag,pErrLog);
            }
        
            virtual HRESULT STDMETHODCALLTYPE Save( IPropertyBag2 *pPropBag,BOOL fClearDirty,BOOL fSaveAllProperties)
            {
                return static_cast<Type*>(comObject)->Save( pPropBag,fClearDirty,fSaveAllProperties);
            }
        
            virtual HRESULT STDMETHODCALLTYPE IsDirty( )
            {
                return static_cast<Type*>(comObject)->IsDirty( );
            }

        };


        
        template< typename Type_, typename Interface_ = IPersistMemory >
        class IPersistMemoryImpl : public IPersistImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IPersistMemory InterfaceType;

            typedef IPersistImpl< Type_, Interface_ > Base;
            IPersistMemoryImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IPersistStreamInit,this);
            }

            virtual HRESULT STDMETHODCALLTYPE IsDirty( )
            {
                return static_cast<Type*>(comObject)->IsDirty( );
            }

            virtual HRESULT STDMETHODCALLTYPE Load( LPVOID pMem,ULONG cbSize)
            {
                return static_cast<Type*>(comObject)->Load( pMem,cbSize);
            }

            virtual HRESULT STDMETHODCALLTYPE Save( LPVOID pMem,BOOL fClearDirty,ULONG cbSize)
            {
                return static_cast<Type*>(comObject)->Save( pMem,fClearDirty,cbSize);
            }

            virtual HRESULT STDMETHODCALLTYPE GetSizeMax( ULONG *pCbSize)
            {
                return static_cast<Type*>(comObject)->GetSizeMax( pCbSize);
            }

            virtual HRESULT STDMETHODCALLTYPE InitNew( )
            {
                return static_cast<Type*>(comObject)->InitNew( );
            }
        };

        template< typename Type_, typename Interface_ = IPersistStreamInit >
        class IPersistStreamInitImpl : public IPersistImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IPersistStreamInit InterfaceType;

            typedef IPersistImpl< Type_, Interface_ > Base;
            IPersistStreamInitImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IPersistStreamInit,this);
            }

            virtual HRESULT STDMETHODCALLTYPE IsDirty( )
            {
                return static_cast<Type*>(comObject)->IsDirty( );
            }
            virtual HRESULT STDMETHODCALLTYPE Load( LPSTREAM pStm)
            {
                return static_cast<Type*>(comObject)->Load( pStm);
            }
            virtual HRESULT STDMETHODCALLTYPE Save( LPSTREAM pStm, BOOL fClearDirty)
            {
                return static_cast<Type*>(comObject)->Save( pStm, fClearDirty);
            }
            virtual HRESULT STDMETHODCALLTYPE GetSizeMax(ULARGE_INTEGER *pCbSize)
            {
                return static_cast<Type*>(comObject)->GetSizeMax(pCbSize);
            }
            virtual HRESULT STDMETHODCALLTYPE InitNew( )
            {
                return static_cast<Type*>(comObject)->InitNew( );
            }

        };


        template< typename Type_, typename Interface_ = IPersistPropertyBag >
        class IPersistPropertyBagImpl : public IPersistImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IPersistPropertyBag InterfaceType;

            typedef IPersistImpl< Type_, Interface_ > Base;
            IPersistPropertyBagImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IPersistPropertyBag,this);
            }

            virtual HRESULT STDMETHODCALLTYPE InitNew( )
            {
                return static_cast<Type*>(comObject)->InitNew( );
            }
            virtual HRESULT STDMETHODCALLTYPE Load( IPropertyBag *pPropBag, IErrorLog *pErrorLog)
            {
                return static_cast<Type*>(comObject)->Load( pPropBag, pErrorLog);
            }
            virtual HRESULT STDMETHODCALLTYPE Save( IPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties)
            {
                return static_cast<Type*>(comObject)->Save( pPropBag, fClearDirty, fSaveAllProperties);
            }
        };


        template< typename Type_, typename Interface_ = IPersistStorage >
        class IPersistStorageImpl : public IPersistImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IPersistStorage InterfaceType;

            typedef IPersistImpl< Type_, Interface_ > Base;
            IPersistStorageImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IPersistStorage,this);
            }

            virtual HRESULT STDMETHODCALLTYPE IsDirty( )
            {
                return static_cast<Type*>(comObject)->IsDirty( );
            }
            virtual HRESULT STDMETHODCALLTYPE InitNew(IStorage *pStg)
            {
                return static_cast<Type*>(comObject)->InitNew(pStg);
            }
            virtual HRESULT STDMETHODCALLTYPE Load(IStorage *pStg )
            {
                return static_cast<Type*>(comObject)->Load(pStg );
            }
            virtual HRESULT STDMETHODCALLTYPE Save( IStorage *pStgSave, BOOL fSameAsLoad)
            {
                return static_cast<Type*>(comObject)->Save( pStgSave, fSameAsLoad);
            }
            virtual HRESULT STDMETHODCALLTYPE SaveCompleted( IStorage *pStgNew)
            {
                return static_cast<Type*>(comObject)->SaveCompleted( pStgNew);
            }
            virtual HRESULT STDMETHODCALLTYPE HandsOffStorage( )
            {
                return static_cast<Type*>(comObject)->HandsOffStorage( );
            }

        };


        template< typename Type_, typename Interface_ = ISimpleFrameSite >
        class ISimpleFrameSiteImpl : public IUnknownImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef ISimpleFrameSite InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            ISimpleFrameSiteImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE PreMessageFilter( HWND hWnd,UINT msg,WPARAM wp,LPARAM lp,LRESULT *plResult,DWORD *pdwCookie)
            {
                return static_cast<Type*>(comObject)->PreMessageFilter( hWnd,msg,wp,lp,plResult,pdwCookie);
            }
            virtual HRESULT STDMETHODCALLTYPE PostMessageFilter( HWND hWnd,UINT msg,WPARAM wp,LPARAM lp,LRESULT *plResult,DWORD dwCookie)
            {
                return static_cast<Type*>(comObject)->PostMessageFilter( hWnd,msg,wp,lp,plResult,dwCookie);
            }
        };

        
        template< typename Type_, typename Interface_ = IAdviseSink >
        class IAdviseSinkImpl : public IUnknownImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IAdviseSink InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IAdviseSinkImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual void STDMETHODCALLTYPE OnDataChange( FORMATETC *pFormatetc,STGMEDIUM *pStgmed)
            {
                return static_cast<Type*>(comObject)->OnDataChange( pFormatetc,pStgmed);
            }
            virtual void STDMETHODCALLTYPE OnViewChange( DWORD dwAspect,LONG lindex)
            {
                return static_cast<Type*>(comObject)->OnViewChange( dwAspect,lindex);
            }
        
            virtual void STDMETHODCALLTYPE OnRename( IMoniker *pmk)
            {
                return static_cast<Type*>(comObject)->OnRename( pmk);
            }
        
            virtual void STDMETHODCALLTYPE OnSave( )
            {
                return static_cast<Type*>(comObject)->OnSave( );
            }
        
            virtual void STDMETHODCALLTYPE OnClose( )
            {
                return static_cast<Type*>(comObject)->OnClose( );
            }
        };

        
        template< typename Type_, typename Interface_ = IAdviseSinkEx >
        class IAdviseSinkExImpl : public IAdviseSinkImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IAdviseSinkEx InterfaceType;

            typedef IAdviseSinkImpl< Type_, Interface_ > Base;
            IAdviseSinkExImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual void STDMETHODCALLTYPE OnViewStatusChange( DWORD dwViewStatus)
            {
                return static_cast<Type*>(comObject)->OnViewStatusChange( dwViewStatus);
            }
        };


        template< typename Type_, typename Interface_ = IFont >
        class IFontImpl : public IUnknownImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IFont InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IFontImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE get_Name( BSTR *pName)
            {
                return static_cast<Type*>(comObject)->get_Name(pName);
            }
            virtual HRESULT STDMETHODCALLTYPE put_Name( BSTR name)
            {
                return static_cast<Type*>(comObject)->put_Name( name);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_Size( CY *pSize)
            {
                return static_cast<Type*>(comObject)->get_Size( pSize);
            }
        
            virtual HRESULT STDMETHODCALLTYPE put_Size( CY size)
            {
                return static_cast<Type*>(comObject)->put_Size( size);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_Bold( BOOL *pBold)
            {
                return static_cast<Type*>(comObject)->get_Bold( pBold);
            }
        
            virtual HRESULT STDMETHODCALLTYPE put_Bold( BOOL bold)
            {
                return static_cast<Type*>(comObject)->put_Bold( bold);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_Italic( BOOL *pItalic)
            {
                return static_cast<Type*>(comObject)->get_Italic( pItalic);
            }
        
            virtual HRESULT STDMETHODCALLTYPE put_Italic( BOOL italic)
            {
                return static_cast<Type*>(comObject)->put_Italic( italic);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_Underline( BOOL *pUnderline)
            {
                return static_cast<Type*>(comObject)->get_Underline( pUnderline);
            }
        
            virtual HRESULT STDMETHODCALLTYPE put_Underline( BOOL underline)
            {
                return static_cast<Type*>(comObject)->put_Underline( underline);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_Strikethrough( BOOL *pStrikethrough)
            {
                return static_cast<Type*>(comObject)->get_Strikethrough( pStrikethrough);
            }
        
            virtual HRESULT STDMETHODCALLTYPE put_Strikethrough( BOOL strikethrough)
            {
                return static_cast<Type*>(comObject)->put_Strikethrough( strikethrough);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_Weight( SHORT *pWeight)
            {
                return static_cast<Type*>(comObject)->get_Weight( pWeight);
            }
        
            virtual HRESULT STDMETHODCALLTYPE put_Weight( SHORT weight)
            {
                return static_cast<Type*>(comObject)->put_Weight( weight);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_Charset(SHORT *pCharset)
            {
                return static_cast<Type*>(comObject)->get_Charset(pCharset);
            }
        
            virtual HRESULT STDMETHODCALLTYPE put_Charset(SHORT charset)
            {
                return static_cast<Type*>(comObject)->put_Charset(charset);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_hFont( HFONT *phFont)
            {
                return static_cast<Type*>(comObject)->get_hFont( phFont);
            }
        
            virtual HRESULT STDMETHODCALLTYPE Clone( IFont **ppFont)
            {
                return static_cast<Type*>(comObject)->Clone( ppFont);
            }
        
            virtual HRESULT STDMETHODCALLTYPE IsEqual( IFont *pFontOther)
            {
                return static_cast<Type*>(comObject)->IsEqual( pFontOther);
            }
        
            virtual HRESULT STDMETHODCALLTYPE SetRatio( LONG cyLogical,LONG cyHimetric)
            {
                return static_cast<Type*>(comObject)->SetRatio( cyLogical,cyHimetric);
            }
        
            virtual HRESULT STDMETHODCALLTYPE QueryTextMetrics( TEXTMETRICOLE *pTM)
            {
                return static_cast<Type*>(comObject)->QueryTextMetrics( pTM);
            }
        
            virtual HRESULT STDMETHODCALLTYPE AddRefHfont( HFONT hFont)
            {
                return static_cast<Type*>(comObject)->AddRefHfont( hFont);
            }
        
            virtual HRESULT STDMETHODCALLTYPE ReleaseHfont( HFONT hFont)
            {
                return static_cast<Type*>(comObject)->ReleaseHfont( hFont);
            }
        
            virtual HRESULT STDMETHODCALLTYPE SetHdc( HDC hDC)
            {
                return static_cast<Type*>(comObject)->SetHdc( hDC);
            }

        };


        
        template< typename Type_, typename Interface_ = IPicture >
        class IPictureImpl : public IUnknownImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IPicture InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IPictureImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE get_Handle( OLE_HANDLE *pHandle)
            {
                return static_cast<Type*>(comObject)->get_Handle( pHandle);
            }
            virtual HRESULT STDMETHODCALLTYPE get_hPal( OLE_HANDLE *phPal)
            {
                return static_cast<Type*>(comObject)->get_hPal( phPal);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_Type( SHORT *pType)
            {
                return static_cast<Type*>(comObject)->get_Type( pType);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_Width(OLE_XSIZE_HIMETRIC *pWidth)
            {
                return static_cast<Type*>(comObject)->get_Width(pWidth);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_Height( OLE_YSIZE_HIMETRIC *pHeight)
            {
                return static_cast<Type*>(comObject)->get_Height( pHeight);
            }
        
            virtual HRESULT STDMETHODCALLTYPE Render( HDC hDC,LONG x,LONG y,LONG cx,LONG cy,OLE_XPOS_HIMETRIC xSrc,OLE_YPOS_HIMETRIC ySrc,OLE_XSIZE_HIMETRIC cxSrc,OLE_YSIZE_HIMETRIC cySrc,LPCRECT pRcWBounds)
            {
                return static_cast<Type*>(comObject)->Render( hDC,x,y,cx,cy,xSrc,ySrc,cxSrc,cySrc,pRcWBounds);
            }
        
            virtual HRESULT STDMETHODCALLTYPE set_hPal( OLE_HANDLE hPal)
            {
                return static_cast<Type*>(comObject)->set_hPal( hPal);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_CurDC(HDC *phDC)
            {
                return static_cast<Type*>(comObject)->get_CurDC(phDC);
            }
        
            virtual HRESULT STDMETHODCALLTYPE SelectPicture( HDC hDCIn,HDC *phDCOut,OLE_HANDLE *phBmpOut)
            {
                return static_cast<Type*>(comObject)->SelectPicture( hDCIn,phDCOut,phBmpOut);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_KeepOriginalFormat( BOOL *pKeep)
            {
                return static_cast<Type*>(comObject)->get_KeepOriginalFormat( pKeep);
            }
        
            virtual HRESULT STDMETHODCALLTYPE put_KeepOriginalFormat( BOOL keep)
            {
                return static_cast<Type*>(comObject)->put_KeepOriginalFormat( keep);
            }
        
            virtual HRESULT STDMETHODCALLTYPE PictureChanged( )
            {
                return static_cast<Type*>(comObject)->PictureChanged( );
            }
        
            virtual HRESULT STDMETHODCALLTYPE SaveAsFile( LPSTREAM pStream,BOOL fSaveMemCopy,LONG *pCbSize)
            {
                return static_cast<Type*>(comObject)->SaveAsFile( pStream,fSaveMemCopy,pCbSize);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_Attributes( DWORD *pDwAttr)
            {
                return static_cast<Type*>(comObject)->get_Attributes( pDwAttr);
            }

        };


        template< typename Type_, typename Interface_ = IPicture2 >
        class IPicture2Impl : public IUnknownImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IPicture2 InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IPicture2Impl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }
            virtual HRESULT STDMETHODCALLTYPE get_Handle( HHANDLE *pHandle)
            {
                return static_cast<Type*>(comObject)->get_Handle( pHandle);
            }
            virtual HRESULT STDMETHODCALLTYPE get_hPal( HHANDLE *phPal)
            {
                return static_cast<Type*>(comObject)->get_hPal( phPal);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_Type( SHORT *pType)
            {
                return static_cast<Type*>(comObject)->get_Type( pType);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_Width(OLE_XSIZE_HIMETRIC *pWidth)
            {
                return static_cast<Type*>(comObject)->get_Width(pWidth);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_Height( OLE_YSIZE_HIMETRIC *pHeight)
            {
                return static_cast<Type*>(comObject)->get_Height( pHeight);
            }
        
            virtual HRESULT STDMETHODCALLTYPE Render( HDC hDC,LONG x,LONG y,LONG cx,LONG cy,OLE_XPOS_HIMETRIC xSrc,OLE_YPOS_HIMETRIC ySrc,OLE_XSIZE_HIMETRIC cxSrc,OLE_YSIZE_HIMETRIC cySrc,LPCRECT pRcWBounds)
            {
                return static_cast<Type*>(comObject)->Render( hDC,x,y,cx,cy,xSrc,ySrc,cxSrc,cySrc,pRcWBounds);
            }
        
            virtual HRESULT STDMETHODCALLTYPE set_hPal( HHANDLE hPal)
            {
                return static_cast<Type*>(comObject)->set_hPal( hPal);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_CurDC( HDC *phDC)
            {
                return static_cast<Type*>(comObject)->get_CurDC( phDC);
            }
        
            virtual HRESULT STDMETHODCALLTYPE SelectPicture( HDC hDCIn,HDC *phDCOut,HHANDLE *phBmpOut)
            {
                return static_cast<Type*>(comObject)->SelectPicture( hDCIn,phDCOut,phBmpOut);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_KeepOriginalFormat( BOOL *pKeep)
            {
                return static_cast<Type*>(comObject)->get_KeepOriginalFormat( pKeep);
            }
        
            virtual HRESULT STDMETHODCALLTYPE put_KeepOriginalFormat( BOOL keep)
            {
                return static_cast<Type*>(comObject)->put_KeepOriginalFormat( keep);
            }
        
            virtual HRESULT STDMETHODCALLTYPE PictureChanged( )
            {
                return static_cast<Type*>(comObject)->PictureChanged( );
            }
        
            virtual HRESULT STDMETHODCALLTYPE SaveAsFile( LPSTREAM pStream,BOOL fSaveMemCopy,LONG *pCbSize)
            {
                return static_cast<Type*>(comObject)->SaveAsFile( pStream,fSaveMemCopy,pCbSize);
            }
        
            virtual HRESULT STDMETHODCALLTYPE get_Attributes( DWORD *pDwAttr)
            {
                return static_cast<Type*>(comObject)->get_Attributes( pDwAttr);
            }
        };

        template< typename Type_, typename Interface_ = IFontEventsDisp >
        class IFontEventsDispImpl : public IDispatchImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IFontEventsDisp InterfaceType;

            typedef IDispatchImpl< Type_, Interface_ > Base;
             IFontEventsDispImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }
        };

        template< typename Type_, typename Interface_ = IFontDisp >
        class IFontDispImpl : public IDispatchImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IFontDisp InterfaceType;

            typedef IDispatchImpl< Type_, Interface_ > Base;
             IFontDispImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }
        };


        template< typename Type_, typename Interface_ = IPictureDisp >
        class IPictureDispImpl : public IDispatchImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IPictureDisp InterfaceType;

            typedef IDispatchImpl< Type_, Interface_ > Base;
             IPictureDispImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }
        };





        template< typename Type_, typename Interface_ = IQuickActivate >
        class IQuickActivateImpl : public IUnknownImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IQuickActivate InterfaceType;

            typedef IUnknownImpl< Type_, Interface_ > Base;
            IQuickActivateImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IQuickActivate,this);
            }

            virtual HRESULT STDMETHODCALLTYPE QuickActivate( QACONTAINER *pQaContainer, QACONTROL *pQaControl)
            {
                return static_cast<Type*>(comObject)->QuickActivate( pQaContainer, pQaControl);
            }
            virtual HRESULT STDMETHODCALLTYPE SetContentExtent(LPSIZEL pSizel)
            {
                return static_cast<Type*>(comObject)->SetContentExtent(pSizel);
            }
            virtual HRESULT STDMETHODCALLTYPE GetContentExtent(LPSIZEL pSizel)
            {
                return static_cast<Type*>(comObject)->GetContentExtent(pSizel);
            }

        };

        template< typename Type_, typename Interface_ = IDropTarget >
        class IDropTargetImpl : public IUnknownImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IDropTarget InterfaceType;

            typedef IUnknownImpl< Type_ , Interface_> Base;
            IDropTargetImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IDropTarget,this);
            }

            virtual HRESULT STDMETHODCALLTYPE DragEnter( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
            {
                return static_cast<Type*>(comObject)->DragEnter( pDataObj, grfKeyState, pt, pdwEffect);
            }
            virtual HRESULT STDMETHODCALLTYPE DragOver( DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
            {
                return static_cast<Type*>(comObject)->DragOver( grfKeyState, pt, pdwEffect);
            }
            virtual HRESULT STDMETHODCALLTYPE DragLeave( )
            {
                return static_cast<Type*>(comObject)->DragLeave( );
            }
            virtual HRESULT STDMETHODCALLTYPE Drop( IDataObject *pDataObj,DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
            {
                return static_cast<Type*>(comObject)->Drop( pDataObj,grfKeyState, pt, pdwEffect);
            }
        };


        
        template< typename Type_, typename Interface_ = IDropSourceNotify >
        class IDropSourceNotifyImpl : public IUnknownImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IDropSourceNotify InterfaceType;

            typedef IUnknownImpl< Type_ , Interface_> Base;
            IDropSourceNotifyImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE DragEnterTarget( HWND hwndTarget)
            {
                return static_cast<Type*>(comObject)->DragEnterTarget( hwndTarget);
            }
            virtual HRESULT STDMETHODCALLTYPE DragLeaveTarget( )
            {
                return static_cast<Type*>(comObject)->DragLeaveTarget( );
            }
        };

        
        template< typename Type_, typename Interface_ = IEnumOLEVERB >
        class IEnumOLEVERBImpl : public IUnknownImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IEnumOLEVERB InterfaceType;

            typedef IUnknownImpl< Type_ , Interface_> Base;
            IEnumOLEVERBImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE Next( ULONG celt,LPOLEVERB rgelt,ULONG *pceltFetched)
            {
                return static_cast<Type*>(comObject)->Next( celt,rgelt,pceltFetched);
            }
            virtual HRESULT STDMETHODCALLTYPE Skip( ULONG celt)
            {
                return static_cast<Type*>(comObject)->Skip(celt);
            }
            virtual HRESULT STDMETHODCALLTYPE Reset( )
            {
                return static_cast<Type*>(comObject)->Reset( );
            }
            virtual HRESULT STDMETHODCALLTYPE Clone( IEnumOLEVERB **ppenum)
            {
                return static_cast<Type*>(comObject)->Clone( ppenum);
            }

        };


        template< typename Type_, typename Interface_ = IDropSource >
        class IDropSourceImpl : public IUnknownImpl< Type_, Interface_ >
        {
            
        public:
            typedef Type_ Type;
            typedef IDropSource InterfaceType;

            typedef IUnknownImpl< Type_ , Interface_> Base;
            IDropSourceImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IDropSource,this);
            }

            virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag( BOOL fEscapePressed, DWORD grfKeyState)
            {
                return static_cast<Type*>(comObject)->QueryContinueDrag( fEscapePressed, grfKeyState);
            }
            virtual HRESULT STDMETHODCALLTYPE GiveFeedback( DWORD dwEffect)
            {
                return static_cast<Type*>(comObject)->GiveFeedback(dwEffect);
            }

        };

        template< typename Type_, typename Interface_ = IEnumConnectionPoints >
        class IEnumConnectionPointsImpl : public IUnknownImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IEnumConnectionPoints InterfaceType;

            typedef IUnknownImpl< Type_ , Interface_> Base;
            IEnumConnectionPointsImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IEnumConnectionPoints,this);
            }

            virtual HRESULT STDMETHODCALLTYPE Next( ULONG cConnections,LPCONNECTIONPOINT *ppCP,ULONG *pcFetched)
            {
                return static_cast<Type*>(comObject)->Next( cConnections,ppCP,pcFetched);
            }
            virtual HRESULT STDMETHODCALLTYPE Skip( ULONG cConnections)
            {
                return static_cast<Type*>(comObject)->Skip(cConnections);
            }
            virtual HRESULT STDMETHODCALLTYPE Reset( )
            {
                return static_cast<Type*>(comObject)->Reset( );
            }
            virtual HRESULT STDMETHODCALLTYPE Clone( IEnumConnectionPoints **ppEnum)
            {
                return static_cast<Type*>(comObject)->Clone( ppEnum );
            }
        };


        template< typename Type_, typename Interface_ = IConnectionPointContainer >
        class IConnectionPointContainerImpl : public IUnknownImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IConnectionPointContainer InterfaceType;

            typedef IUnknownImpl< Type_ , Interface_> Base;
            IConnectionPointContainerImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IConnectionPointContainer,this);
            }

            virtual HRESULT STDMETHODCALLTYPE EnumConnectionPoints( IEnumConnectionPoints **ppEnum)
            {
                return static_cast<Type*>(comObject)->EnumConnectionPoints( ppEnum );
            }
        
            virtual HRESULT STDMETHODCALLTYPE FindConnectionPoint( REFIID riid, IConnectionPoint **ppCP)
            {
                return static_cast<Type*>(comObject)->FindConnectionPoint( riid, ppCP);
            }
        };

        template< typename Type_, typename Interface_ = IEnumConnections >
        class IEnumConnectionsImpl : public IUnknownImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IEnumConnections InterfaceType;

            typedef IUnknownImpl< Type_ , Interface_> Base;
            IEnumConnectionsImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IEnumConnections,this);
            }

            virtual HRESULT STDMETHODCALLTYPE Next( ULONG cConnections,LPCONNECTDATA rgcd,ULONG *pcFetched)
            {
                return static_cast<Type*>(comObject)->Next( cConnections,rgcd,pcFetched);
            }
            virtual HRESULT STDMETHODCALLTYPE Skip( ULONG cConnections)
            {
                return static_cast<Type*>(comObject)->Skip( cConnections);
            }
            virtual HRESULT STDMETHODCALLTYPE Reset( )
            {
                return static_cast<Type*>(comObject)->Reset( );
            }
            virtual HRESULT STDMETHODCALLTYPE Clone( IEnumConnections **ppEnum)
            {
                return static_cast<Type*>(comObject)->Clone( ppEnum );
            }
        };


        template< typename Type_, typename Interface_ = IConnectionPoint >
        class IConnectionPointImpl : public IUnknownImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IConnectionPoint InterfaceType;

            typedef IUnknownImpl< Type_ , Interface_> Base;
            IConnectionPointImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(IID_IConnectionPoint,this);
            }

            virtual HRESULT STDMETHODCALLTYPE GetConnectionInterface( IID *pIID)
            {
                return static_cast<Type*>(comObject)->GetConnectionInterface(pIID);
            }
            virtual HRESULT STDMETHODCALLTYPE GetConnectionPointContainer(IConnectionPointContainer **ppCPC)
            {
                return static_cast<Type*>(comObject)->GetConnectionPointContainer(ppCPC);
            }
            virtual HRESULT STDMETHODCALLTYPE Advise( IUnknown *pUnkSink,DWORD *pdwCookie)
            {
                return static_cast<Type*>(comObject)->Advise( pUnkSink,pdwCookie);
            }
            virtual HRESULT STDMETHODCALLTYPE Unadvise( DWORD dwCookie)
            {
                return static_cast<Type*>(comObject)->Unadvise(dwCookie);
            }
            virtual HRESULT STDMETHODCALLTYPE EnumConnections( IEnumConnections **ppEnum)
            {
                return static_cast<Type*>(comObject)->EnumConnections(ppEnum);
            }
        };

        
        template< typename Type_, typename Interface_ = IOleUIObjInfoW >
        class IOleUIObjInfoImpl : public IUnknownImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IOleUIObjInfoW InterfaceType;

            typedef IUnknownImpl< Type_ , Interface_> Base;
            IOleUIObjInfoImpl(Type_* theObject)
                : Base(theObject)
            {
                // {66571CAF-F6AB-48B4-ABB0-AE511A3EA068}
                GUID IID_IOleUIObjInfo = { 0x66571caf, 0xf6ab, 0x48b4, { 0xab, 0xb0, 0xae, 0x51, 0x1a, 0x3e, 0xa0, 0x68 } };

                static_cast<Type*>(comObject)->InternalAddInterface(IID_IOleUIObjInfo,this);
            }
        
            virtual HRESULT STDMETHODCALLTYPE GetObjectInfo(DWORD dwObject,DWORD* lpdwObjSize, LPWSTR * lplpszLabel,LPWSTR FAR* lplpszType, LPWSTR * lplpszShortType,LPWSTR * lplpszLocation)
            {
                return static_cast<Type*>(comObject)->GetObjectInfo(dwObject,lpdwObjSize, lplpszLabel,lplpszType, lplpszShortType,lplpszLocation);
            }
            virtual HRESULT STDMETHODCALLTYPE GetConvertInfo(DWORD dwObject,
                CLSID * lpClassID, WORD * lpwFormat,
                CLSID * lpConvertDefaultClassID,
                LPCLSID * lplpClsidExclude, UINT * lpcClsidExclude)
            {
                return static_cast<Type*>(comObject)->GetConvertInfo(dwObject,
                                                    lpClassID, lpwFormat,
                                                    lpConvertDefaultClassID,
                                                    lplpClsidExclude, lpcClsidExclude);
            }
            virtual HRESULT STDMETHODCALLTYPE ConvertObject(DWORD dwObject, REFCLSID clsidNew)
            {
                return static_cast<Type*>(comObject)->ConvertObject(dwObject, clsidNew);
            }
            
            virtual HRESULT STDMETHODCALLTYPE GetViewInfo (DWORD dwObject,HGLOBAL * phMetaPict, DWORD* pdvAspect, int* pnCurrentScale)
            {
                return static_cast<Type*>(comObject)->GetViewInfo (dwObject,phMetaPict, pdvAspect, pnCurrentScale);
            }
            virtual HRESULT STDMETHODCALLTYPE SetViewInfo (DWORD dwObject,HGLOBAL hMetaPict, DWORD dvAspect,int nCurrentScale, BOOL bRelativeToOrig)
            {
                return static_cast<Type*>(comObject)->SetViewInfo (dwObject,hMetaPict, dvAspect,nCurrentScale, bRelativeToOrig);
            }
        };


        template< typename Type_, typename Interface_ = IOleDocumentSite >
        class IOleDocumentSiteImpl : public IUnknownImpl< Type_, Interface_ >
        {
        public:
            typedef Type_ Type;
            typedef IOleDocumentSite InterfaceType;

            typedef IUnknownImpl< Type_ , Interface_> Base;
            IOleDocumentSiteImpl(Type_* theObject)
                : Base(theObject)
            {
                static_cast<Type*>(comObject)->InternalAddInterface(__uuidof(InterfaceType),this);
            }

            virtual HRESULT STDMETHODCALLTYPE ActivateMe(IOleDocumentView *pViewToActivate)
            {
                return static_cast<Type*>(comObject)->ActivateMe(pViewToActivate);
            }
        };



        template <typename ContainerType>
        class ComContainerEnumAdapterBase
        {
            
        public:
            typedef ContainerType container_type;
            typedef typename ContainerType::value_type value_type;
            typedef typename ContainerType::const_iterator const_iterator;
            typedef typename ContainerType::iterator iterator;
        private:
            container_type container;
            const_iterator current;
            size_t size;
            size_t index;
        public:
            ComContainerEnumAdapterBase( const ContainerType& theContainer )
                : container(theContainer)
            {
                current = container.cbegin();
                size = container.size();
                index = 0;
            }

            ComContainerEnumAdapterBase( const ComContainerEnumAdapterBase& theAdapter )
                : container(theAdapter.container)
            {
                index = theAdapter.index;
                current = container.cbegin() + index;
                size = container.size();
            }


            const_iterator Current() const
            {
                return current;
            }

            const_iterator Begin() const
            {
                return container.cbegin();
            }

            const_iterator End()
            {
                return container.cend();
            }


            HRESULT Reset()
            {
                current = container.cbegin();
                index = 0;
            }

            HRESULT Skip(ULONG numberOfElementsToSkip)
            {
                if( numberOfElementsToSkip + index > size )
                {
                    index = size;
                    current = container.cend();
                    return S_FALSE;
                }
                else
                {
                    index += numberOfElementsToSkip;
                    current += numberOfElementsToSkip;
                    return S_OK;
                }
            }

            size_t Remaining() const
            {
                return size - index;
            }

            bool Next()
            {
                if(current == container.cend())
                {
                    current++;
                    index++;
                }
                return current != container.cend();
            }

            bool CanMove() const
            {
                return current != container.cend();
            }

        };

        template <typename ContainerType, typename ComEnumElementType>
        class ComContainerEnumAdapter : public ComContainerEnumAdapterBase<ContainerType>
        {
        public:
            typedef ComContainerEnumAdapterBase<ContainerType> Base;
            typedef ComEnumElementType EnumElementType;

            ComContainerEnumAdapter( const ContainerType& theContainer )
                : Base(theContainer)
            {
            }

            HRESULT AssignTo(ComEnumElementType& destination) const
	        { 
                auto current = Current();
                if(!CanMove())
                {
                    return S_FALSE;
                }
                destination = *current;
                return S_OK;
	        }
        };


        template <typename ContainerType>
        class ComContainerEnumAdapter<ContainerType, VARIANT> : public ComContainerEnumAdapterBase<ContainerType>
        {
        public:
            typedef ComContainerEnumAdapterBase<ContainerType> Base;
            typedef VARIANT EnumElementType;

            ComContainerEnumAdapter( const ContainerType& theContainer )
                : Base(theContainer)
            {
            }

            HRESULT AssignTo(VARIANT& destination) const
	        { 
                auto current = Current();
                if(!CanMove())
                {
                    return S_FALSE;
                }
                const Variant& refVariant = *current;
                auto result = refVariant.AssignTo(destination);
                return result;
	        }
        };

        template <typename ContainerType>
        class ComContainerEnumAdapter<ContainerType, CONNECTDATA> : public ComContainerEnumAdapterBase<ContainerType>
        {
        public:
            typedef ComContainerEnumAdapterBase<ContainerType> Base;
            typedef CONNECTDATA EnumElementType;

            ComContainerEnumAdapter( const ContainerType& theContainer )
                : Base(theContainer)
            {
            }

            HRESULT AssignTo(CONNECTDATA& destination) const
	        { 
                Base::const_iterator current = Current();
                if(!CanMove())
                {
                    return S_FALSE;
                }
                const ConnectData& refConnectData = *current;
                auto result = refConnectData.AssignTo(destination);
                return result;
	        }
        };


        template <typename ContainerType>
        class ComContainerEnumAdapter<ContainerType, IUnknown*> : public ComContainerEnumAdapterBase<ContainerType>
        {
        public:
            typedef ComContainerEnumAdapterBase<ContainerType> Base;
            typedef IUnknown* EnumElementType;

            ComContainerEnumAdapter( const ContainerType& theContainer )
                : Base(theContainer)
            {
            }

            HRESULT AssignTo(EnumElementType& destination) const
	        { 
                Base::const_iterator current = Current();
                if(!CanMove())
                {
                    return S_FALSE;
                }
                const Unknown& refUnknown = *current;
                destination = refUnknown.GetInterfacePointer<IUnknown>();
                destination->AddRef();
                return S_OK;
	        }
        }; 


        template <typename ContainerType>
        class ComContainerEnumAdapter<ContainerType, LPCONNECTIONPOINT> : public ComContainerEnumAdapterBase<ContainerType>
        {
        public:
            typedef ComContainerEnumAdapterBase<ContainerType> Base;
            typedef LPCONNECTIONPOINT EnumElementType;

            ComContainerEnumAdapter( const ContainerType& theContainer )
                : Base(theContainer)
            {
            }

            HRESULT AssignTo(EnumElementType& destination) const
	        { 
                Base::const_iterator current = Current();
                if(!CanMove())
                {
                    return S_FALSE;
                }
                const ConnectionPoint& refConnectionPoint = *current;
                destination = refConnectionPoint.GetInterfacePointer<IConnectionPoint>();
                destination->AddRef();
                return S_OK;
	        }
        };


        template <typename ContainerType>
        class ComContainerEnumAdapter<ContainerType, LPOLESTR> : public ComContainerEnumAdapterBase<ContainerType>
        {
        public:
            typedef ComContainerEnumAdapterBase<ContainerType> Base;
            typedef LPOLESTR EnumElementType;

            ComContainerEnumAdapter( const ContainerType& theContainer )
                : Base(theContainer)
            {
            }

            HRESULT AssignTo(EnumElementType& destination) const
	        { 
                Base::const_iterator current = Current();
                if(!CanMove())
                {
                    return S_FALSE;
                }
                const String& refString = *current;
                ULONG len = ULONG(refString.length() + 1);
                destination = (LPOLESTR)CoTaskMemAlloc(len);
                if (destination == nullptr)
		        {
			        return E_OUTOFMEMORY;
		        }
                if(len == 1)
                {
                    destination[0] = 0;
                }
                else
                {
                    wcscpy_s((wchar_t*)destination,len,refString.c_str());
                    destination[len - 1] = 0;
                }
                return S_OK;
	        }
        };





        /*

        template<>
        class ComCopyPolicy<OLEVERB>
        {
        public:
	        static HRESULT Copy(const OLEVERB* source, OLEVERB* destination)
	        {
		        HRESULT hr = S_OK;
		        *destination = *source;
		        if (source->lpszVerbName == NULL)
		        {
			        return S_OK;
		        }

		        ULONG len = wcslen(source->lpszVerbName)+1;
		        destination->lpszVerbName = (LPOLESTR)CoTaskMemAlloc(len);

		        if (destination->lpszVerbName == NULL)
		        {
			        hr = E_OUTOFMEMORY;
		        }
		        else
		        {
                    wcscpy_s((wchar_t*)destination->lpszVerbName,len,(wchar_t*)source->lpszVerbName);
		        }
		        return hr;
	        }
	        static void Initialize(OLEVERB* p) 
	        { 
                memset(p,0,sizeof(OLEVERB));
	        }
	        static void Destroy(OLEVERB* p) 
	        { 
		        if (p->lpszVerbName)
		        {
			        CoTaskMemFree(p->lpszVerbName);
		        }
	        }
        };

        */



        template <typename Type_, typename ContainerEnumAdapterType ,typename InterfaceImpl >
        class ComEnum : public ComObjectBase
        {
        public:
            typedef ComObjectBase Base;
            typedef typename InterfaceImpl::InterfaceType InterfaceType;
            typedef typename ContainerEnumAdapterType::container_type container_type;
            typedef typename ContainerEnumAdapterType::EnumElementType EnumElementType;
        private:
            InterfaceImpl interfaceImpl;
            ContainerEnumAdapterType containerEnumAdapter;
        public:
            ComEnum(const container_type& theElements)
                  : Base(),
                    interfaceImpl((Type_*)this),
                    containerEnumAdapter(theElements)
            {}

            ComEnum(IUnknown* theOuterUnknown, const container_type& theElements)
                  : Base(theOuterUnknown),
                    interfaceImpl((Type_*)this),
                    containerEnumAdapter(theElements)
            {}

            explicit ComEnum(const ComEnum& other)
                : Base(other),
                  interfaceImpl((Type_*)this),
                  containerEnumAdapter(other.containerEnumAdapter)
            {
            }

            virtual HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid,void ** ppvObject)
            {
                return Base::QueryInterface( riid,ppvObject);
            }

            virtual ULONG STDMETHODCALLTYPE AddRef( )
            {
                return Base::AddRef( );
            }

            virtual ULONG STDMETHODCALLTYPE Release( )
            {
                return Base::Release( );
            }

            HRESULT STDMETHODCALLTYPE Next( ULONG numberOfElementsToFetch,EnumElementType* fetchedElements,ULONG *numberOfFetchedElements)
            {
                if (fetchedElements == NULL || (numberOfElementsToFetch > 1 && numberOfFetchedElements == NULL))
                {
		            return E_POINTER;
                }
                if (numberOfFetchedElements != NULL)
                {
		            *numberOfFetchedElements = 0;
                }
	            
                if(containerEnumAdapter.CanMove() == false)
                {
                    return S_FALSE;
                }

	            size_t numberOfRemainingElements = containerEnumAdapter.Remaining();
                size_t actualNumberOfElementsToFetch;
	            HRESULT result = S_OK;
	            if (numberOfRemainingElements < numberOfElementsToFetch)
                {
                    result = S_FALSE;
                    actualNumberOfElementsToFetch = numberOfRemainingElements;
                }
                else
                {
                    actualNumberOfElementsToFetch = numberOfElementsToFetch;
                }
	
                for(size_t i = 0; i < actualNumberOfElementsToFetch;i++)
	            {
                    result = containerEnumAdapter.AssignTo(fetchedElements[i]);
                    if(FAILED(result))
                    {
                        return result;
                    }
                    if (numberOfFetchedElements != NULL)
                    {
		                *numberOfFetchedElements ++;
                    }

                    if(!containerEnumAdapter.Next())
                    {
                        break;
                    }
	            }
	            return result;
            }
            HRESULT STDMETHODCALLTYPE Skip( ULONG numberOfElementsToSkip )
            {
                return containerEnumAdapter.Skip(numberOfElementsToSkip);
            }
            HRESULT STDMETHODCALLTYPE Reset( )
            {
                return containerEnumAdapter.Reset( );
            }
            HRESULT STDMETHODCALLTYPE Clone( InterfaceType **ppEnum)
            {
                ComEnum* pEnum = new ComEnum(*this);
                auto result = pEnum->InternalQueryInterface(__uuidof(InterfaceType),(void**)ppEnum);
                pEnum->Release();
                return result;
            }
        };

        class ComEnumConnections : 
            public ComEnum<
                    ComEnumConnections,
                    ComContainerEnumAdapter< std::vector<ConnectData> , CONNECTDATA>,
                    IEnumConnectionsImpl<ComEnumConnections> >
        {
        public:
            typedef ComEnum<ComEnumConnections,ComContainerEnumAdapter< std::vector<ConnectData> , CONNECTDATA>,IEnumConnectionsImpl<ComEnumConnections> > Base;

            ComEnumConnections( const std::vector<ConnectData>& theElements)
                  : Base(theElements)
            {
            }

            ComEnumConnections( IUnknown* pOuterUnknown ,const std::vector<ConnectData>& theElements)
                  : Base(pOuterUnknown,theElements)
            {
            }
        };


        class ComEnumConnectionPoints : 
            public ComEnum<
                    ComEnumConnectionPoints,
                    ComContainerEnumAdapter< std::vector<ConnectionPoint> , LPCONNECTIONPOINT>,
                    IEnumConnectionPointsImpl<ComEnumConnectionPoints> >
        {
        public:
            typedef ComEnum<
                    ComEnumConnectionPoints,
                    ComContainerEnumAdapter< std::vector<ConnectionPoint> , LPCONNECTIONPOINT>,
                    IEnumConnectionPointsImpl<ComEnumConnectionPoints> > Base;

            ComEnumConnectionPoints( const std::vector<ConnectionPoint>& theElements)
                  : Base(theElements)
            {
            }

            ComEnumConnectionPoints( IUnknown* pOuterUnknown ,const std::vector<ConnectionPoint>& theElements)
                  : Base(pOuterUnknown,theElements)
            {
            }
        };


        class ComEnumUnknown : 
            public ComEnum<
                    ComEnumUnknown,
                    ComContainerEnumAdapter< std::vector<Unknown> , IUnknown*>,
                    IEnumUnknownImpl<ComEnumUnknown> >
        {
        public:
            typedef ComEnum<
                    ComEnumUnknown,
                    ComContainerEnumAdapter< std::vector<Unknown> , IUnknown*>,
                    IEnumUnknownImpl<ComEnumUnknown> > Base;

            ComEnumUnknown( const std::vector<Unknown>& theElements)
                  : Base(theElements)
            {
            }

            ComEnumUnknown( IUnknown* pOuterUnknown ,const std::vector<Unknown>& theElements)
                  : Base(pOuterUnknown,theElements)
            {
            }
        };





        class ComEnumVARIANT : 
            public ComEnum<
                    ComEnumVARIANT,
                    ComContainerEnumAdapter< std::vector<Variant> , VARIANT>,
                    IEnumVARIANTImpl<ComEnumVARIANT> >
        {
        public:
            typedef ComEnum<
                    ComEnumVARIANT,
                    ComContainerEnumAdapter< std::vector<Variant> , VARIANT>,
                    IEnumVARIANTImpl<ComEnumVARIANT> > Base;

            ComEnumVARIANT( const std::vector<Variant>& theElements)
                  : Base(theElements)
            {
            }

            ComEnumVARIANT( IUnknown* pOuterUnknown ,const std::vector<Variant>& theElements)
                  : Base(pOuterUnknown,theElements)
            {
            }
        };


        class ComEnumString : 
            public ComEnum<
                    ComEnumString,
                    ComContainerEnumAdapter< std::vector<String> , LPOLESTR>,
                    IEnumStringImpl<ComEnumString> >
        {
        public:
            typedef ComEnum<
                    ComEnumString,
                    ComContainerEnumAdapter< std::vector<String> , LPOLESTR>,
                    IEnumStringImpl<ComEnumString> > Base;

            ComEnumString( const std::vector<String>& theElements)
                  : Base(theElements)
            {
            }

            ComEnumString( IUnknown* pOuterUnknown ,const std::vector<String>& theElements)
                  : Base(pOuterUnknown,theElements)
            {
            }
        };








    };
};



#endif // __HWINOBJIMPL_H__